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

Hi,
I know it is recommended to use eq to do string comparison,
but is == cause undefined behaviour? I tried this
$a = "mssql"; if ($a == "mssql") {print "equal\n";} # gets print out as equal $a = "MSSQL"; if ($a == "mssql") {print "equal\n";} # print equal if ($a eq "mssql") {print "equal\n";} # print nothing
so it seems to be it is a case sensitive side effect but the
comparison still goes on. But my coworker says the behaviour
is undefined. Can anyone tell? Thanks

Replies are listed 'Best First'.
Re: is behaviour undefined for string comparision with ==
by GrandFather (Saint) on Feb 16, 2006 at 22:48 UTC

    == numifies its arguments. Non-numeric strings numify as 0 so all such strings equal each other and equal 0 when using ==. Consider:

    use strict; #use warnings; sub match { my ($lhs, $rhs) = @_; print "$lhs == $rhs\n" if $lhs == $rhs; print "$lhs != $rhs\n" if $lhs != $rhs; } match ('0', '1'); match ('0', '0'); match ('1', '1'); match ('0xxx', '1xxx'); match ('0xxx', '0xxx'); match ('0', 'YYY'); match ('xxx', 'yyy'); match ('yyy', 'YYY');

    Prints:

    0 != 1 0 == 0 1 == 1 0xxx != 1xxx 0xxx == 0xxx 0 == YYY xxx == yyy yyy == YYY

    Note that warnings are not enabled, otherwise you will get a bunch of warnings at runtime.


    DWIM is Perl's answer to Gödel
Re: is behaviour undefined for string comparision with ==
by salva (Canon) on Feb 16, 2006 at 22:44 UTC
    the behaviour is well defined, left and right arguments to == are converted to numbers, yielding 0 in that case, and then compared. On my computer I get the expected
    equal equal

    If you get something different, you are doing something wrong or you have found a bug. Which version of perl and OS are you using?

      I enable warnings and thus I get:
      Argument "mssql" isn't numeric in numeric eq (==) at test.pl line 3. Argument "mssql" isn't numeric in numeric eq (==) at test.pl line 3. equal Argument "mssql" isn't numeric in numeric eq (==) at test.pl line 5. Argument "MSSQL" isn't numeric in numeric eq (==) at test.pl line 5. equal

      Enough clues, already?

      actually the second comparions should be an eq. I mistyped.
      I just not believe the behaviour is not well defined as my
      coworker says. Because string will act like integer for Hex based like 'A', and we can do + - * / on it. I do not see
      why Perl is unable to do that for ==. Any Perl language specification reference to this? I want to convince her.
      Thanks

        See Equality Operators in perlop and perlnumber may help

        Point your coworker to this thread - she may become so enamoured of PerlMonks that she joins. :)


        DWIM is Perl's answer to Gödel

        It's very well defined. If you string contains numerals, then the numerals will be converted to numbers. Strings without numerals will be converted to zero. The following code will consider the two strings as equal:

        my $str1 = "perl123"; my $str2 = "aaaa123"; if ($str1 == $str2) { print "Strings are equal\n"; }

        You can check out perldoc perlop to find more information on this.

Re: is behaviour undefined for string comparision with ==
by ikegami (Patriarch) on Feb 17, 2006 at 00:02 UTC

    You've silently edited your post. That's going to confuse people reading the existing replies. Normally, you'd mark what you updated. Now, about your new question:

    No, == on strings is very well defined. The string arguments will first be converted to numbers. Strings that don't look like a number get converted to zero.

    Yes, eq is case-senstive. If you wish to do a case-insensitive compare, use
    if (lc($a) eq "mssql")

    By the way, $a and $b are special variables. You should avoid them.