Why doesn't this 'next if' work?

Discussion in 'Perl Misc' started by Max Moor, Jul 15, 2009.

  1. Max Moor

    Max Moor Guest

    Hi All,

    I'm fairly new to perl, and have already fixed this problem, but I
    want to understand why it didn't work before.

    This is the original, non-working code:

    @o_list = ();
    foreach my $o ( @{$stuff->{thingys}} ) {

    # Exclude if no match
    $match = 'n';
    foreach $thingy (@test_thingys) {

    if ($o->{thingy} == $thingy) {
    $match = 'y';
    last;
    }
    }
    next if ($match != 'y');

    push @o_list, $o;
    }

    Basically, its running through a list of "thingys", checking to see if
    the item matches any of a list of test "thingys." Before checking the list,
    I set $match to 'n'. If I find a match, I set it to 'y' and dump out of the
    loop. At least, that was the intent. What really happened was that "next
    if" line never ran, and all items got pushed onto "o_list." I did some
    checking, and found that $match equaled 'n'. The line simply wasn't ever
    running.

    The working snippet...

    @o_list = ();
    foreach my $o ( @{$stuff->{thingys}} ) {

    # Exclude if no match
    $match = 0;
    foreach $thingy (@test_thingys) {

    if ($o->{thingy} == $thingy) {
    $match = 1;
    last;
    }
    }
    next if (!match);

    push @o_list, $o;
    }

    The only change was the "flag" values. Instead of 'y' and 'n', it's
    now 0 and 1.

    Can anyone tell me what about the 'n' and 'y' messed up the logic?

    Thanks for your help,
    Max
     
    Max Moor, Jul 15, 2009
    #1
    1. Advertising

  2. Max Moor

    Uri Guttman Guest

    >>>>> "MM" == Max Moor <maxmoor@remove_hotmail.com> writes:

    MM> next if ($match != 'y');

    that does a numeric comparison. 'n' is 0 and so is 'y' so that will
    never be true. use eq for string compares. if you had enabled warnings
    perl would have told you this. also you aren't using strict which helps
    too. ask perl for all the help it can give you.

    now the bigger picture is you shouldn't be using boolean flags like that
    in general. proper use of next/last will eliminate the need for them. i
    don't have the time to review the logic but others may do so.

    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, Jul 15, 2009
    #2
    1. Advertising

  3. Max Moor

    Max Moor Guest

    Uri Guttman <> wrote in
    news::

    >>>>>> "MM" == Max Moor <maxmoor@remove_hotmail.com> writes:

    >
    > MM> next if ($match != 'y');
    >
    > that does a numeric comparison. 'n' is 0 and so is 'y' so that will
    > never be true. use eq for string compares. if you had enabled warnings
    > perl would have told you this. also you aren't using strict which helps
    > too. ask perl for all the help it can give you.
    >
    > now the bigger picture is you shouldn't be using boolean flags like that
    > in general. proper use of next/last will eliminate the need for them. i
    > don't have the time to review the logic but others may do so.
    >
    > uri
    >


    Hi uri,

    Thanks for the answer. Makes sense.

    I also agree with you about flags, but there's still alot of ugly in
    this code. It's really just an eval block inside a larger perl script that
    we users on a particular site are allowed access to. We can use it to
    price check items we have for sale.

    I'm a C programmer from way back, but haven't done perl before. I
    started with the code as generated by an auto-writer they provide.
    Hopefully I'll get to know my way around perl well enough that some things
    like bad logic will get cleaned up.

    I'll see what I can do to add warnings and strict-ness. I'm not sure
    how that might affect the larger script I don't have say over.

    Anyway, thanks again for the knowledge. I appreciate the help.

    - Max
     
    Max Moor, Jul 15, 2009
    #3
  4. Max Moor

    Guest

    On 15 Jul 2009 19:24:27 GMT, Max Moor <maxmoor@remove_hotmail.com> wrote:

    >Hi All,
    >
    > I'm fairly new to perl, and have already fixed this problem, but I
    >want to understand why it didn't work before.
    >
    > This is the original, non-working code:
    >
    >@o_list = ();
    >foreach my $o ( @{$stuff->{thingys}} ) {
    >
    > # Exclude if no match
    > $match = 'n';
    > foreach $thingy (@test_thingys) {
    >
    > if ($o->{thingy} == $thingy) {


    if .. == .. or .. eq ..
    > $match = 'y';
    > last;
    > }
    > }
    > next if ($match != 'y');


    if .. != .. or .. ne ..
    >
    > push @o_list, $o;
    >}


    Take your pick. Not both.

    -sln
     
    , Jul 15, 2009
    #4
  5. Max Moor

    Doug Miller Guest

    In article <>, wrote:
    >On 15 Jul 2009 19:24:27 GMT, Max Moor <maxmoor@remove_hotmail.com> wrote:
    >
    >>Hi All,
    >>
    >> I'm fairly new to perl, and have already fixed this problem, but I
    >>want to understand why it didn't work before.
    >>
    >> This is the original, non-working code:
    >>
    >>@o_list = ();
    >>foreach my $o ( @{$stuff->{thingys}} ) {
    >>
    >> # Exclude if no match
    >> $match = 'n';
    >> foreach $thingy (@test_thingys) {
    >>
    >> if ($o->{thingy} == $thingy) {

    >
    >if .. == .. or .. eq ..


    depending on the type of the two operands.

    >> $match = 'y';
    >> last;
    >> }
    >> }
    >> next if ($match != 'y');

    >
    >if .. != .. or .. ne ..


    Wrong. ne is necessary for string comparisons.
    >>
    >> push @o_list, $o;
    >>}

    >
    >Take your pick. Not both.


    Nonsense. $match, being assigned values of either 'n' or 'y', clearly requires
    the string inequality operator ne. He can't "take [his] pick" there.

    Likewise, he can't pick and choose in the other comparison either. If the
    operands are numeric, he *must* use ==; if they are strings, he *must* use eq.
     
    Doug Miller, Jul 15, 2009
    #5
  6. Max Moor

    Guest

    On Wed, 15 Jul 2009 21:50:44 GMT, (Doug Miller) wrote:

    >In article <>, wrote:
    >>On 15 Jul 2009 19:24:27 GMT, Max Moor <maxmoor@remove_hotmail.com> wrote:
    >>
    >>>Hi All,
    >>>
    >>> I'm fairly new to perl, and have already fixed this problem, but I
    >>>want to understand why it didn't work before.
    >>>
    >>> This is the original, non-working code:
    >>>
    >>>@o_list = ();
    >>>foreach my $o ( @{$stuff->{thingys}} ) {
    >>>
    >>> # Exclude if no match
    >>> $match = 'n';
    >>> foreach $thingy (@test_thingys) {
    >>>
    >>> if ($o->{thingy} == $thingy) {

    >>
    >>if .. == .. or .. eq ..

    >
    >depending on the type of the two operands.
    >
    >>> $match = 'y';
    >>> last;
    >>> }
    >>> }
    >>> next if ($match != 'y');

    >>
    >>if .. != .. or .. ne ..

    >
    >Wrong. ne is necessary for string comparisons.
    >>>
    >>> push @o_list, $o;
    >>>}

    >>
    >>Take your pick. Not both.

    >
    >Nonsense. $match, being assigned values of either 'n' or 'y', clearly requires
    >the string inequality operator ne. He can't "take [his] pick" there.
    >
    >Likewise, he can't pick and choose in the other comparison either. If the
    >operands are numeric, he *must* use ==; if they are strings, he *must* use eq.

    ^^^^^^^^^^^^^^^^^^^^^^^^^
    Nonsense, 2 == ... and 2 eq ...

    -sln
     
    , Jul 15, 2009
    #6
  7. Max Moor

    Guest

    On Wed, 15 Jul 2009 14:59:39 -0700, wrote:

    >On Wed, 15 Jul 2009 21:50:44 GMT, (Doug Miller) wrote:
    >
    >>In article <>, wrote:
    >>>On 15 Jul 2009 19:24:27 GMT, Max Moor <maxmoor@remove_hotmail.com> wrote:
    >>>
    >>>>Hi All,
    >>>>
    >>>> I'm fairly new to perl, and have already fixed this problem, but I
    >>>>want to understand why it didn't work before.
    >>>>
    >>>> This is the original, non-working code:
    >>>>
    >>>>@o_list = ();
    >>>>foreach my $o ( @{$stuff->{thingys}} ) {
    >>>>
    >>>> # Exclude if no match
    >>>> $match = 'n';
    >>>> foreach $thingy (@test_thingys) {
    >>>>
    >>>> if ($o->{thingy} == $thingy) {
    >>>
    >>>if .. == .. or .. eq ..

    >>
    >>depending on the type of the two operands.
    >>
    >>>> $match = 'y';
    >>>> last;
    >>>> }
    >>>> }
    >>>> next if ($match != 'y');
    >>>
    >>>if .. != .. or .. ne ..

    >>
    >>Wrong. ne is necessary for string comparisons.
    >>>>
    >>>> push @o_list, $o;
    >>>>}
    >>>
    >>>Take your pick. Not both.

    >>
    >>Nonsense. $match, being assigned values of either 'n' or 'y', clearly requires
    >>the string inequality operator ne. He can't "take [his] pick" there.
    >>
    >>Likewise, he can't pick and choose in the other comparison either. If the
    >>operands are numeric, he *must* use ==; if they are strings, he *must* use eq.

    > ^^^^^^^^^^^^^^^^^^^^^^^^^
    >Nonsense, 2 == ... and 2 eq ...
    >
    >-sln


    There should actually be a 2 e= ... operator, no need for conversion (if necessary).

    -sln
     
    , Jul 15, 2009
    #7
  8. Max Moor

    Guest

    On Wed, 15 Jul 2009 21:50:44 GMT, (Doug Miller) wrote:

    >In article <>, wrote:
    >>On 15 Jul 2009 19:24:27 GMT, Max Moor <maxmoor@remove_hotmail.com> wrote:
    >>
    >>>Hi All,
    >>>
    >>> I'm fairly new to perl, and have already fixed this problem, but I
    >>>want to understand why it didn't work before.
    >>>
    >>> This is the original, non-working code:
    >>>
    >>>@o_list = ();
    >>>foreach my $o ( @{$stuff->{thingys}} ) {
    >>>
    >>> # Exclude if no match
    >>> $match = 'n';
    >>> foreach $thingy (@test_thingys) {
    >>>
    >>> if ($o->{thingy} == $thingy) {

    >>
    >>if .. == .. or .. eq ..

    >
    >depending on the type of the two operands.
    >
    >>> $match = 'y';
    >>> last;
    >>> }
    >>> }
    >>> next if ($match != 'y');

    >>
    >>if .. != .. or .. ne ..

    >
    >Wrong. ne is necessary for string comparisons.
    >>>
    >>> push @o_list, $o;
    >>>}

    >>
    >>Take your pick. Not both.

    >
    >Nonsense. $match, being assigned values of either 'n' or 'y', clearly requires
    >the string inequality operator ne. He can't "take [his] pick" there.
    >
    >Likewise, he can't pick and choose in the other comparison either. If the
    >operands are numeric, he *must* use ==; if they are strings, he *must* use eq.


    But, match != 'y' is valid, isin't it? Isin't that valid???

    -sln
     
    , Jul 15, 2009
    #8
  9. (Doug Miller) wrote:
    >Likewise, he can't pick and choose in the other comparison either. If the
    >operands are numeric, he *must* use ==; if they are strings, he *must* use eq.


    Actually you can mix and match. But you better know exactly what you are
    doing.

    There is nothing stopping you from comparing the string values of two
    numbers and actually of the top my head I can't think of a scenario,
    where you would get an unexpected surprise.

    And you can also compare the numerical values of two strings. However in
    this case you really better know what those numerical values are going
    to be because most of the time it's probably not what you would expect.

    jue
     
    Jürgen Exner, Jul 16, 2009
    #9
  10. Max Moor

    Guest

    On Wed, 15 Jul 2009 16:11:33 -0700, Jürgen Exner <> wrote:

    > (Doug Miller) wrote:
    >>Likewise, he can't pick and choose in the other comparison either. If the
    >>operands are numeric, he *must* use ==; if they are strings, he *must* use eq.

    >
    >Actually you can mix and match. But you better know exactly what you are
    >doing.
    >
    >There is nothing stopping you from comparing the string values of two
    >numbers and actually of the top my head I can't think of a scenario,
    >where you would get an unexpected surprise.
    >
    >And you can also compare the numerical values of two strings. However in
    >this case you really better know what those numerical values are going
    >to be because most of the time it's probably not what you would expect.
    >
    >jue


    Very well said.

    -sln
     
    , Jul 16, 2009
    #10
  11. Max Moor

    Doug Miller Guest

    In article <>, Jürgen Exner <> wrote:
    > (Doug Miller) wrote:
    >>Likewise, he can't pick and choose in the other comparison either. If the
    >>operands are numeric, he *must* use ==; if they are strings, he *must* use eq.

    >
    >Actually you can mix and match. But you better know exactly what you are
    >doing.
    >
    >There is nothing stopping you from comparing the string values of two
    >numbers


    As long as you consider unexpected results to be "nothing".

    > and actually of the top my head I can't think of a scenario,
    >where you would get an unexpected surprise.


    I can...

    1 gt 02
    -1 lt -2
    1 ne 01
    -0 ne 0
    1 ne +1
    +1 lt -1
    8 ne 010
    15 ne 0xF
    0xF ne 0xf
    >
    >And you can also compare the numerical values of two strings. However in
    >this case you really better know what those numerical values are going
    >to be because most of the time it's probably not what you would expect.


    OK, perhaps I should have added "... if he plans on getting the results that a
    naive failure to understand the difference would lead him to expect." <g>
     
    Doug Miller, Jul 16, 2009
    #11
  12. Max Moor

    Guest

    On Thu, 16 Jul 2009 01:38:14 GMT, (Doug Miller) wrote:

    >In article <>, Jürgen Exner <> wrote:
    >> (Doug Miller) wrote:
    >>>Likewise, he can't pick and choose in the other comparison either. If the
    >>>operands are numeric, he *must* use ==; if they are strings, he *must* use eq.

    >>
    >>Actually you can mix and match. But you better know exactly what you are
    >>doing.
    >>
    >>There is nothing stopping you from comparing the string values of two
    >>numbers

    >
    >As long as you consider unexpected results to be "nothing".
    >
    >> and actually of the top my head I can't think of a scenario,
    >>where you would get an unexpected surprise.

    >
    >I can...
    >
    >1 gt 02
    >-1 lt -2
    >1 ne 01
    >-0 ne 0
    >1 ne +1
    >+1 lt -1
    >8 ne 010
    >15 ne 0xF
    >0xF ne 0xf
    >>
    >>And you can also compare the numerical values of two strings. However in
    >>this case you really better know what those numerical values are going
    >>to be because most of the time it's probably not what you would expect.

    >
    >OK, perhaps I should have added "... if he plans on getting the results that a
    >naive failure to understand the difference would lead him to expect." <g>


    But, but, the point is that its allowable, not necesarily always right.

    -sln
     
    , Jul 16, 2009
    #12
  13. Max Moor

    Guest

    On Thu, 16 Jul 2009 03:05:39 +0100, Ben Morrow <> wrote:

    >
    >Quoth (Doug Miller):
    >> In article <>, Jürgen Exner
    >> <> wrote:
    >> > (Doug Miller) wrote:
    >> >>Likewise, he can't pick and choose in the other comparison either. If the
    >> >>operands are numeric, he *must* use ==; if they are strings, he *must* use eq.
    >> >
    >> >Actually you can mix and match. But you better know exactly what you are
    >> >doing.
    >> >
    >> >There is nothing stopping you from comparing the string values of two
    >> >numbers

    >>
    >> As long as you consider unexpected results to be "nothing".
    >>
    >> > and actually of the top my head I can't think of a scenario,
    >> >where you would get an unexpected surprise.

    >>
    >> I can...
    >>
    >> 1 gt 02
    >> -1 lt -2
    >> 1 ne 01
    >> -0 ne 0
    >> 1 ne +1
    >> +1 lt -1
    >> 8 ne 010
    >> 15 ne 0xF
    >> 0xF ne 0xf

    >
    >Only one of these gives a different result from a numerical comparison.
    >On systems that support IEEE floats, you can add
    >
    > -0.0 ne 0
    >
    >Of course, if you replace all those literal numbers with quoted strings,
    >they all compare different numerically, though in some cases this is
    >because they don't numify as you might expect.
    >
    >> >And you can also compare the numerical values of two strings. However in
    >> >this case you really better know what those numerical values are going
    >> >to be because most of the time it's probably not what you would expect.

    >
    >Talking about comparing 'strings' and 'numbers' is incorrect in Perl.
    >The appropriate question is 'do you wish to compare string values or
    >numeric values?'.
    >
    >Ben


    Yeah, its a formulea, its undefined too, really, throw that in, but, whats in
    a conversion, nobody wants to know, thats why its !defined $value instead of !$value.

    -sln
     
    , Jul 16, 2009
    #13
    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. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    978
    Mark Rae
    Dec 21, 2006
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,222
    Smokey Grindel
    Dec 2, 2006
  3. Deniz Bahar
    Replies:
    2
    Views:
    512
    Andrey Tarasevich
    Mar 9, 2005
  4. dave rose
    Replies:
    2
    Views:
    86
    Chris Hulan
    Jul 7, 2006
  5. William Bryant
    Replies:
    18
    Views:
    189
    William Bryant
    Sep 14, 2013
Loading...

Share This Page