freestyling has asked for the wisdom of the Perl Monks concerning the following question:

I know that you are supposed t use eq rather than == for comparing text, but I have the problem that in the function:
foreach $member (@ops) { if ($member == $who) { $op = 1; last; } }
I get told by perl to replace == with eq but when I do that the comparison no longer works, and returns false everytime. What am I doing wrong??

Replies are listed 'Best First'.
Re: == works where it shouldn't but eq doesn't where it should
by Corion (Patriarch) on Jan 15, 2006 at 22:21 UTC

    Whenever Perl tells you that two strings are not equal, odds are that Perl is propably right.

    As you don't show any data, I can only guess: You have a list of names in @ops, and you read in another name, put it into the variable $who, and now try to check whether $who is a member of @ops. Then, it is likely that whitespace in one of the fields is tripping you.

    Make sure you print your data before and after, and look out for whitespace:

    foreach $member (@ops) { print "Comparing member '$member' against '$who'\n"; if ($member eq $who) { $op = 1; last; }; };

    Coincidentially, you might later on move to a more perlish construct:

    $op = grep { $_ eq $who } @ops ? 1 : 0;
      Which, by the way, is inefficient as it iterates through the whole @ops array even if the first element matches $who! A better approach is first in List::Util.
      if (first { $_ eq $who } @ops) { print "matches"; }
Re: == works where it shouldn't but eq doesn't where it should
by brian_d_foy (Abbot) on Jan 15, 2006 at 22:42 UTC

    You've left out a lot of the problem, but it looks like you might want a hash instead of an array. In your example, it looks like you simply want to check if an element is in the array.

    Once you have the hash, you can use exists to check if the key is there. You won't have to go through a bunch of other elements and you won't have to care about comparing elements. :)

    my %ops = map { $_, 1 } @ops; # create the hash however you like my $op = exists $ops{$member} ? 1 : 0;

    Alberto Simões talks more about this sort of thing in his article "Array Anti-Patterns" in the Fall 2005 issue of The Perl Review. :)

    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review
Re: == works where it shouldn't but eq doesn't where it should
by helphand (Pilgrim) on Jan 15, 2006 at 22:20 UTC

    You left out a lot of detail, like the rest of the code. The comparison $member == $who is legitimate syntax, and if I make some assumptions about the surrounding code, it works fine here.

    use strict; my @ops = ( 1 .. 20 ); my $who = 10; my $op; foreach my $member (@ops) { if ($member == $who) { $op = 1; last; } } print "Found one\n" if $op;

    Perhaps you could give us more detail to work with?

    Scott

Re: == works where it shouldn't but eq doesn't where it should
by jZed (Prior) on Jan 15, 2006 at 22:25 UTC
    As Corion said, whitespace is one possible reason that two strings you think are equal might not be equal to perl. Another possible reason is case - if one string is in upper case and the other in lower case, they will not be treated as equal. To get around that use something like (lc $member eq lc $who).
Re: == works where it shouldn't but eq doesn't where it should
by Errto (Vicar) on Jan 16, 2006 at 00:53 UTC
    The explanation, I suspect, for the first part of your issue is that when you compare two non-numeric strings using ==, they both get converted to zero and thus are reported as equal. So if you're comparing strings you really need to use eq and not ==.
Re: == works where it shouldn't but eq doesn't where it should
by tweetiepooh (Hermit) on Jan 16, 2006 at 11:08 UTC
    If $who is keyed in did you remove the carriage return?
    $ perl -e 'print "fred" eq "fred\n" ? "t" : "f","\n";' f $ perl -e 'print "fred" == "fred\n" ? "t" : "f","\n";' t