Problem with loop control LAST exiting prematurely

Discussion in 'Perl Misc' started by Rodion, Mar 18, 2008.

  1. Rodion

    Rodion Guest

    Hi!
    I got into a problem with looking up stuff in hasheshes, the sub is
    supposed to check if $data is in the hash, and when found exit the loop,
    as there is no need to go through the rest of the hash.
    Only for some reason it exits immediately :?

    the code:
    --------
    CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
    switch ($test){
    case 'numbers' {
    if ($data==$k){
    $found=1;
    last CODECHECK if ($found==1);
    }
    }
    case 'text' {
    if ($data eq $k){
    $found=1;
    last CODECHECK if ($found==1);
    }
    }
    }
    }
    -----------
    The problem is that last exits the loop before $found is set which
    shouldnt happen.

    TIA!


    --

    Professor: Now, be careful, Fry. And if you kill anyone, make sure
    to eat their heart to gain their courage. Their rich tasty courage.
    Rodion, Mar 18, 2008
    #1
    1. Advertising

  2. Rodion

    Willem Guest

    Rodion wrote:
    ) Hi!
    ) I got into a problem with looking up stuff in hasheshes, the sub is
    ) supposed to check if $data is in the hash, and when found exit the loop,
    ) as there is no need to go through the rest of the hash.
    ) Only for some reason it exits immediately :?
    )
    ) the code:
    ) --------
    ) CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
    ) switch ($test){
    ) case 'numbers' {
    ) if ($data==$k){
    ) $found=1;
    ) last CODECHECK if ($found==1);
    ) }
    ) }
    ) case 'text' {
    ) if ($data eq $k){
    ) $found=1;
    ) last CODECHECK if ($found==1);
    ) }
    ) }
    ) }
    ) }
    ) -----------
    ) The problem is that last exits the loop before $found is set which
    ) shouldnt happen.

    How do you know that it's the 'last' that is exiting the loop ?


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
    Willem, Mar 18, 2008
    #2
    1. Advertising

  3. Rodion

    Rodion Guest

    Jednom davno, ne znam vise kad, Willem duboko zamisljen/a rece:

    > Rodion wrote:
    > ) The problem is that last exits the loop before $found is set which
    > ) shouldnt happen.
    >
    > How do you know that it's the 'last' that is exiting the loop ?


    Easily, if I comment it out, it works correctly, albait slowly as it has
    to go through the whole hash which is unnaceptable :(


    --

    Professor: Now, be careful, Fry. And if you kill anyone, make sure
    to eat their heart to gain their courage. Their rich tasty courage.
    Rodion, Mar 18, 2008
    #3
  4. Rodion wrote:
    > Hi!
    > I got into a problem with looking up stuff in hasheshes, the sub is
    > supposed to check if $data is in the hash, and when found exit the loop,
    > as there is no need to go through the rest of the hash.
    > Only for some reason it exits immediately :?
    >
    > the code:
    > --------
    > CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
    > switch ($test){
    > case 'numbers' {
    > if ($data==$k){
    > $found=1;
    > last CODECHECK if ($found==1);
    > }
    > }
    > case 'text' {
    > if ($data eq $k){
    > $found=1;
    > last CODECHECK if ($found==1);
    > }
    > }
    > }
    > }
    > -----------
    > The problem is that last exits the loop before $found is set which
    > shouldnt happen.


    Couldn't you just write that as:

    $found = 1 if exists $cb{$cbName}{$data};


    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
    John W. Krahn, Mar 18, 2008
    #4
  5. Rodion

    Rodion Guest

    Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:


    > Couldn't you just write that as:
    >
    > $found = 1 if exists $cb{$cbName}{$data};
    >


    Well I get the same problem, some cases arent found in the hash key...
    I think it's a data type problem...confusing...

    --

    Professor: Now, be careful, Fry. And if you kill anyone, make sure
    to eat their heart to gain their courage. Their rich tasty courage.
    Rodion, Mar 18, 2008
    #5
  6. Rodion

    Rodion Guest

    Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:

    >
    > Couldn't you just write that as:
    >
    > $found = 1 if exists $cb{$cbName}{$data};


    Well, I have to thank you for putting me on the right track!

    There was a problem with some numeric data having prefixed zeroes while
    some of the hash keys did not so there could be no match ( 0567 != 567).
    But I'm still confused why the LAST was triggered before a match was
    $found?

    In any case the code is now much leaner :)

    I heart Perl!

    --

    Professor: Now, be careful, Fry. And if you kill anyone, make sure
    to eat their heart to gain their courage. Their rich tasty courage.
    Rodion, Mar 18, 2008
    #6
  7. Rodion

    Guest

    Rodion <> wrote:
    > Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:
    >
    > >
    > > Couldn't you just write that as:
    > >
    > > $found = 1 if exists $cb{$cbName}{$data};

    >
    > Well, I have to thank you for putting me on the right track!
    >
    > There was a problem with some numeric data having prefixed zeroes while
    > some of the hash keys did not so there could be no match ( 0567 != 567).
    > But I'm still confused why the LAST was triggered before a match was
    > $found?


    I rather doubt that it was doing that. If you want to pursue the matter,
    post a complete, runnable script to illustrate this. Otherwise I'll assume
    you are misinterpreting something.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Mar 18, 2008
    #7
  8. Rodion

    Rodion Guest

    Jednom davno, ne znam vise kad, duboko zamisljen/a
    rece:

    > Rodion <> wrote:
    > > Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:
    > >
    > > >
    > > > Couldn't you just write that as:
    > > >
    > > > $found = 1 if exists $cb{$cbName}{$data};

    > >
    > > Well, I have to thank you for putting me on the right track!
    > >
    > > There was a problem with some numeric data having prefixed zeroes while
    > > some of the hash keys did not so there could be no match ( 0567 != 567).
    > > But I'm still confused why the LAST was triggered before a match was
    > > $found?

    >
    > I rather doubt that it was doing that. If you want to pursue the matter,
    > post a complete, runnable script to illustrate this. Otherwise I'll assume
    > you are misinterpreting something.


    Well, I'm most certanly misundrestanding something, but I'd like to know
    what, so I don't make the same mistake twice :/

    The following subrutine works correctly (and slowly) if the lines with
    LAST are commented out.

    Code:
    sub checkCB{
    my $cbName=$_[0];
    my $data=$_[1];
    my ($k,$v);
    my $found;
    my $g=0;
    my $checked;
    my $test='text';

    print "looking for [$data] in [$cbName] control: ";

    #----numbers exception
    if ($data=~/^\d{1,30}$/){
    $data=int($data);
    $test='numbers';
    }

    CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
    #print $g++."\n";
    switch ($test){
    case 'numbers' {
    if ($data==$k){
    $found=1;
    #last CODECHECK if ($found==1);
    }
    }
    case 'text' {
    if ($data eq $k){
    $found=1;
    #last CODECHECK if ($found==1);
    }
    }
    }
    }

    return $found;
    }
    ---------

    --

    Professor: Now, be careful, Fry. And if you kill anyone, make sure
    to eat their heart to gain their courage. Their rich tasty courage.
    Rodion, Mar 18, 2008
    #8
  9. Rodion wrote:
    > Jednom davno, ne znam vise kad, duboko zamisljen/a
    > rece:
    >
    >> Rodion <> wrote:
    >>> Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:
    >>>
    >>>> Couldn't you just write that as:
    >>>>
    >>>> $found = 1 if exists $cb{$cbName}{$data};
    >>> Well, I have to thank you for putting me on the right track!
    >>>
    >>> There was a problem with some numeric data having prefixed zeroes while
    >>> some of the hash keys did not so there could be no match ( 0567 != 567).
    >>> But I'm still confused why the LAST was triggered before a match was
    >>> $found?

    >> I rather doubt that it was doing that. If you want to pursue the matter,
    >> post a complete, runnable script to illustrate this. Otherwise I'll
    >> assume
    >> you are misinterpreting something.

    > Well, I'm most certanly misundrestanding something, but I'd like to know
    > what, so I don't make the same mistake twice :/
    >
    > The following subrutine works correctly (and slowly) if the lines with
    > LAST are commented out.
    >
    > Code:
    >
    > sub checkCB{
    > my $cbName=$_[0];
    > my $data=$_[1];
    > my ($k,$v);
    > my $found;
    > my $g=0;
    > my $checked;
    > my $test='text';
    >
    > print "looking for [$data] in [$cbName] control: ";
    >
    > #----numbers exception
    > if ($data=~/^\d{1,30}$/){
    > $data=int($data);
    > $test='numbers';
    > }
    >
    > CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
    > #print $g++."\n";
    > switch ($test){
    > case 'numbers' {
    > if ($data==$k){
    > $found=1;
    > #last CODECHECK if ($found==1);
    > }
    > }
    > case 'text' {
    > if ($data eq $k){
    > $found=1;
    > #last CODECHECK if ($found==1);
    > }
    > }
    > }
    > }
    >
    > return $found;
    > }
    > ---------
    >

    Ever try using Perl's debugger? Change some of the "last CODECHECK if
    ($found==1)"'s to a full if statement just so you can set break points
    in the debugger and then examine the execution and the data in the
    variables as this subroutine operates. You will learn a ton about how
    Perl works, how your code works or does not work and will not have to
    resort to having others solve your problems. Try it sometime - seriously!
    --
    Andrew DeFaria <http://defaria.com>
    A synonym is a word you use when you can't spell the word you first
    thought of. - Burt Bacharach
    Andrew DeFaria, Mar 18, 2008
    #9
  10. Rodion

    Guest

    Rodion <> wrote:
    > Jednom davno, ne znam vise kad, duboko zamisljen/a
    > rece:
    >
    > > Rodion <> wrote:
    > > > Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a
    > > > rece:
    > > >
    > > > >
    > > > > Couldn't you just write that as:
    > > > >
    > > > > $found = 1 if exists $cb{$cbName}{$data};
    > > >
    > > > Well, I have to thank you for putting me on the right track!
    > > >
    > > > There was a problem with some numeric data having prefixed zeroes
    > > > while some of the hash keys did not so there could be no match ( 0567
    > > > != 567). But I'm still confused why the LAST was triggered before a
    > > > match was $found?

    > >
    > > I rather doubt that it was doing that. If you want to pursue the
    > > matter, post a complete, runnable script to illustrate this. Otherwise
    > > I'll assume you are misinterpreting something.

    >
    > Well, I'm most certanly misundrestanding something, but I'd like to know
    > what, so I don't make the same mistake twice :/
    >
    > The following subrutine works correctly (and slowly) if the lines with
    > LAST are commented out.


    Global symbol "%cb" requires explicit package name...

    And if I make up my own values for %cb, then I don't see what you
    say you see.

    Please post COMPLETE, RUNNABLE code which illustrates that which is to
    be illustrated.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
    , Mar 18, 2008
    #10
  11. Rodion wrote:
    > Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:
    >
    >> Couldn't you just write that as:
    >>
    >> $found = 1 if exists $cb{$cbName}{$data};

    >
    > Well, I have to thank you for putting me on the right track!
    >
    > There was a problem with some numeric data having prefixed zeroes while
    > some of the hash keys did not so there could be no match ( 0567 != 567).


    If you are doing the testing using numeric comparison, then they are equal.

    print "equal" if '0567' == '567';

    --
    -brian
    Brian Helterline, Mar 18, 2008
    #11
  12. On 2008-03-18 15:40, Rodion <> wrote:
    > Jednom davno, ne znam vise kad, duboko zamisljen/a
    > rece:
    >
    >> Rodion <> wrote:
    >> > Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:
    >> > > Couldn't you just write that as:
    >> > >
    >> > > $found = 1 if exists $cb{$cbName}{$data};
    >> >
    >> > Well, I have to thank you for putting me on the right track!
    >> >
    >> > There was a problem with some numeric data having prefixed zeroes while
    >> > some of the hash keys did not so there could be no match ( 0567 != 567).


    Try to canonicalize the data.

    >> > But I'm still confused why the LAST was triggered before a match was
    >> > $found?

    >>
    >> I rather doubt that it was doing that. If you want to pursue the matter,
    >> post a complete, runnable script to illustrate this. Otherwise I'll assume
    >> you are misinterpreting something.

    >
    > Well, I'm most certanly misundrestanding something, but I'd like to know
    > what, so I don't make the same mistake twice :/
    >
    > The following subrutine works correctly (and slowly) if the lines with
    > LAST are commented out.


    How does it not work correctly if these lines are not commented out?

    Please post an example which demonstrates the problem.

    > Code:
    > sub checkCB{
    > my $cbName=$_[0];
    > my $data=$_[1];
    > my ($k,$v);
    > my $found;
    > my $g=0;
    > my $checked;
    > my $test='text';
    >
    > print "looking for [$data] in [$cbName] control: ";
    >
    > #----numbers exception
    > if ($data=~/^\d{1,30}$/){
    > $data=int($data);
    > $test='numbers';
    > }
    >
    > CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
    > #print $g++."\n";
    > switch ($test){


    Don't use switch. It is rather buggy and introduces problems which are
    hard to find.

    > case 'numbers' {
    > if ($data==$k){
    > $found=1;
    > #last CODECHECK if ($found==1);


    $found is always 1 here (you just set it to one), so this is equivalent
    to "last CODECHECK;". However, that seems to be what you want.

    > }
    > }
    > case 'text' {
    > if ($data eq $k){
    > $found=1;
    > #last CODECHECK if ($found==1);


    Same here.

    > }
    > }
    > }
    > }
    >
    > return $found;
    > }
    > ---------
    >
    Peter J. Holzer, Mar 18, 2008
    #12
  13. Frank Seitz wrote:
    >> Why can't programmers tell Haloween from Christmas?
    >>
    >> Because OCT 31 == DEC 25

    > $ perldoc -f dec
    > No documentation for perl function `dec' found

    Some people no sense of humor!
    --
    Andrew DeFaria <http://defaria.com>
    You have the right to remain silent. Anything you say will be misquoted,
    then used against you.
    Andrew DeFaria, Mar 19, 2008
    #13
  14. Frank Seitz wrote:
    > Lawrence Statton wrote:
    >> Frank Seitz <> writes:
    >>> You should test your programs!

    >> lawrence@hummer - /tmp % perl -le 'print "equal" if '0567' == '375''
    >> equal

    >
    > You're right, but it depends on the shell.
    >
    > % perl
    > print "equal\n" if '0567' == '375'
    > ^D
    > %
    >
    > % perl
    > print "equal\n" if '0567' == '567'
    > ^D
    > equal
    > %
    >

    Huh? How are the above two different?
    --
    Andrew DeFaria <http://defaria.com>
    Does it bother you that doctors call what they do a practice?
    Andrew DeFaria, Mar 19, 2008
    #14
  15. Andrew DeFaria wrote:
    > Frank Seitz wrote:
    >>> Why can't programmers tell Haloween from Christmas?
    >>>
    >>> Because OCT 31 == DEC 25

    >> $ perldoc -f dec
    >> No documentation for perl function `dec' found

    > Some people no sense of humor!


    Some people no verb!


    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
    John W. Krahn, Mar 19, 2008
    #15
  16. Rodion

    Rodion Guest

    Jednom davno, ne znam vise kad, Peter J. Holzer duboko zamisljen/a rece:

    > On 2008-03-18 15:40, Rodion <> wrote:
    > > Jednom davno, ne znam vise kad, duboko zamisljen/a
    > > rece:
    > >
    > >> Rodion <> wrote:
    > >> > Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:
    > >> > > Couldn't you just write that as:
    > >> > >
    > >> > > $found = 1 if exists $cb{$cbName}{$data};
    > >> >
    > >> > Well, I have to thank you for putting me on the right track!
    > >> >
    > >> > There was a problem with some numeric data having prefixed zeroes while
    > >> > some of the hash keys did not so there could be no match ( 0567 != 567).

    >
    > Try to canonicalize the data.


    The problem was in my data which became clear when I ditched that ugly
    sub with a more sensible:

    $found = 1 if exists $cb{$cbName}{$data};

    and added a few checks for the data.

    > > switch ($test){

    >
    > Don't use switch. It is rather buggy and introduces problems which are
    > hard to find.


    That sucks. I depend on switch in this for the main part of the program.
    Is it documented?

    > > case 'numbers' {
    > > if ($data==$k){
    > > $found=1;
    > > #last CODECHECK if ($found==1);

    >
    > $found is always 1 here (you just set it to one), so this is equivalent
    > to "last CODECHECK;". However, that seems to be what you want.


    Yes I wrote a lot of silly stuff in a hurry trying to see what is
    happening :/

    Thanks for the help :)

    --

    Professor: Now, be careful, Fry. And if you kill anyone, make sure
    to eat their heart to gain their courage. Their rich tasty courage.
    Rodion, Mar 19, 2008
    #16
  17. Rodion

    Uri Guttman Guest

    >>>>> "R" == Rodion <> writes:

    >> Don't use switch. It is rather buggy and introduces problems which are
    >> hard to find.


    R> That sucks. I depend on switch in this for the main part of the program.
    R> Is it documented?

    no, switch sucks. perl 5.10 has a proper builtin called given/when. and
    for simple string cases a dispatch table is much better. google for that
    phrase in this group as it has been discussed many times.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Free Perl Training --- http://perlhunter.com/college.html ---------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
    Uri Guttman, Mar 19, 2008
    #17
  18. Lawrence Statton wrote:
    > Brian Helterline <> writes:
    >> If you are doing the testing using numeric comparison, then they are equal.
    >>
    >> print "equal" if '0567' == '567';
    >>
    >> --
    >> -brian

    >
    > Does not print "equal"


    It does on my system:


    C:\>perl -le "print 'equal' if '0567' == '567'"
    equal

    C:\>perl -v

    This is perl, v5.8.8 built for MSWin32-x86-multi-thread
    (with 33 registered patches, see perl -V for more detail)
    Brian Helterline, Mar 19, 2008
    #18
  19. Rodion

    Ted Zlatanov Guest

    On Tue, 18 Mar 2008 21:09:03 +0100 Frank Seitz <> wrote:

    >> Why can't programmers tell Haloween from Christmas?
    >>
    >> Because OCT 31 == DEC 25


    FS> $ perldoc -f dec
    FS> No documentation for perl function `dec' found

    Obviously you needed "perldoc -f DEC" :)

    Ted
    Ted Zlatanov, Mar 26, 2008
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Buster Copley

    Exiting a loop half way through

    Buster Copley, Sep 18, 2003, in forum: C++
    Replies:
    5
    Views:
    475
    Buster
    Sep 19, 2003
  2. vineoff

    Exiting from loop

    vineoff, Oct 24, 2005, in forum: C++
    Replies:
    39
    Views:
    926
    =?ISO-8859-15?Q?Juli=E1n?= Albo
    Oct 27, 2005
  3. sLim

    loop not exiting

    sLim, Nov 28, 2009, in forum: C Programming
    Replies:
    1
    Views:
    336
  4. Brad

    Validators in composite control firing prematurely

    Brad, Nov 29, 2005, in forum: ASP .Net Web Controls
    Replies:
    4
    Views:
    189
    Steven Cheng[MSFT]
    Dec 2, 2005
  5. Isaac Won
    Replies:
    9
    Views:
    349
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page