Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Equality operators

by jkva (Chaplain)
on Apr 25, 2006 at 11:31 UTC ( [id://545536]=perlquestion: print w/replies, xml ) Need Help??

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

Wise monks, I lay the following observation before you :

1 == 1; is True.
1 == 2; is False.
'a' == 'a'; is True.
'a' == 'b'; is True.

'1' == '1'; is True.
'1' == '2'; is False.

'1' == '1foo'; is True.
'1' == 'foo1'; is False.


This must have something to do with the way the == equality operator works. Is this documented? I could not find it in the perldocs...Does anymonk have enlightenment?

Replies are listed 'Best First'.
Re: Equality operators
by Hue-Bond (Priest) on Apr 25, 2006 at 11:41 UTC
Re: Equality operators
by BrowserUk (Patriarch) on Apr 25, 2006 at 11:59 UTC

    If you enable warnings, perl will most times tell you quite clearly what you are doing wrong:

    1 == 1; #is True. 1 == 2; #is False. 'a' == 'a'; #is True. Argument "a" isn't numeric in numeric eq (==) at (eval 6) line 1, Argument "a" isn't numeric in numeric eq (==) at (eval 6) line 1, 'a' == 'b'; #is True. Argument "b" isn't numeric in numeric eq (==) at (eval 7) line 1, Argument "a" isn't numeric in numeric eq (==) at (eval 7) line 1, '1' == '1'; #is True. '1' == '2'; #is False. '1' == '1foo'; #is True. Argument "1foo" isn't numeric in numeric eq (==) at (eval 10) line 2, '1' == 'foo1'; #is False. Argument "foo1" isn't numeric in numeric eq (==) at (eval 11) line 1,

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Equality operators
by mantadin (Beadle) on Apr 25, 2006 at 11:40 UTC
    As '==' is the numeric equality operator, it doesn't make sense to use it for strings. For all Strings you should use eq instead of ==, ne instead of != and cmp instead of <=>.
      Mantadin, thank you. I am aware of this, however I am wondering why '1' == '1foo' evals to true while '1' eq 'foo1' does not.

        When converting strings to numbers, Perl only looks at the start of the string. '1foo' becomes 1 and 'foo1' becomes 0.

        --
        <http://dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

        because strings are automatically converted to numbers when needed. '1foo' is converted to 1 and 'foo1' is converted to 0.

        Others have already explained how the conversion works, but if you want to see for yourself the number into which a string is coerced, add 0 to the string.

        print(0+'a', "\n"); # 0 print(0+'b', "\n"); # 0 print(0+'1', "\n"); # 1 print(0+'2', "\n"); # 2 print(0+'1foo', "\n"); # 1 print(0+'foo1', "\n"); # 0
Re: Equality operators
by bart (Canon) on Apr 25, 2006 at 11:43 UTC
    '==' is for numerical comparisons, which means both arguments will be converted to numbers before the actual comparison happens.

    That's why you get warnings if the conversion fails ("foo" isn't numeric) or one of the values is undef.

    The reason why perl has both stringwise and numerical comparisons,, is because you're not really supposed to know whether a scalar contains a string or a number. A value "1" is thought of as being equivalent to just 1. Other languages that have only one equality test operator, like Javascript, VB, and PHP, can cause bugs because it tries to infer what you mean from the type of variable. Which could be different from what you think. Ditto with the concatenation operator, . vs. +.

    p.s. In the CB, jkva seems to have had some doubt on why == is called a "binary operator". The reason is because == has 2 arguments, plain and simple (bi == 2). Likewise, ! is an "unary operator" (un == 1), and ?: is a "ternary operator" (ter == 3).

Re: Equality operators
by davorg (Chancellor) on Apr 25, 2006 at 11:43 UTC

    == is the numeric equality operator. It compares its operands as numbers. Therefore any strings are given a numeric value before the comparison takes place. Perl does this by looking for numbers at the start of the string. If none are found then the string is given the value 0. This is why 'a' and 'b' appear to be equal (they are both converted to zero).

    For string comparisons, use 'eq'.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Equality operators
by GrandFather (Saint) on Apr 25, 2006 at 11:45 UTC

    Perl numifies strings when a number is required. A string that matches /(\d+)\D/ for example simply becomes the integer contained in $1, or 0 if ! defined $1. '1foo' becomes 1. 'foo1' becomes 0.


    DWIM is Perl's answer to Gödel
Re: Equality operators
by blazar (Canon) on Apr 26, 2006 at 10:30 UTC
    In short:
    '==' ne 'eq'; # but '==' == 'eq';
Re: Equality operators
by rhesa (Vicar) on Apr 26, 2006 at 11:37 UTC
    Just to confuse matters a bit, because Perl lets me:
    #!/usr/bin/perl use strict; no warnings; use Scalar::Util qw/ dualvar /; my $foo = dualvar 1, "foo"; my $bar = dualvar 2, "foo"; print "Using dualvar$/"; print '$foo', ($foo eq $bar ? " eq " : " ne "), '$bar', $/; print '$foo', ($foo == $bar ? " == " : " != "), '$bar', $/; __END__ Using dualvar $foo eq $bar $foo != $bar

    Using overload could result in similarly confusing comparisons. This isn't as contrived as it sounds:

    #!/usr/bin/perl use strict; use warnings; use URI; my $foo = URI->new('http://www.perlmonks.org'); my $bar = URI->new('http://www.perlmonks.org'); print "Using URI$/"; print '$foo', ($foo eq $bar ? " eq " : " ne "), '$bar', $/; print '$foo', ($foo == $bar ? " == " : " != "), '$bar', $/; __END__ Using URI $foo eq $bar $foo != $bar

    URI defines an overload for stringification, but not for numification. In numerical context, objects evaluate to their location in memory. And the two different objects are stored in different locations, so == returns false.

    So be careful with == and eq :)

Re: Equality operators
by perladdict (Chaplain) on Apr 25, 2006 at 13:24 UTC
    hi, monks

    #!/usr/bin/perl -w if (1 == 1) { print "triue\n"; } if(1 == 2) { print"false\n"; } if ('a' eq 'b') { print "trie\n"; } if('1'eq '1foo') { print "true\n"; } if('1' eq 'foo1') { print "false\n"; }

    Here is the proper code which prints and checks the conditions properly If it checks for the numberic and strings.
    As per perl comparison, you have to use the above syntax of checking if it in number or strings.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://545536]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (3)
As of 2024-03-28 17:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found