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

eq vs. ==

by c (Hermit)
on Jul 20, 2003 at 10:19 UTC ( [id://276020] : perlquestion . print w/replies, xml ) Need Help??

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

In cleaning up some old code recently, I found a string that can be summed up as:

if ($val eq '2') { print 'foo'; }

This looked glaringly wrong to me, however it works. In my current perl mindset, I immediately want to change this to:

if ($val == '2') { print 'foo'; }

In my script I am sure that the value of $val will alway be numeric if it is defined at all. However, I'm a bit confused about why == exists if eq works correctly. Reading through perldoc perl, I find the following quote:

(Why do we have separate numeric and string comparisons? Because we don't have special variable types, and Perl needs to know whether to sort numerically (where 99 is less than 100) or alphabetically (where 100 comes before 99)

So does == exist to present a full list of numeric comparison options, when it, unto itself is not necessary?


Replies are listed 'Best First'.
Re: eq vs. ==
by liz (Monsignor) on Jul 20, 2003 at 10:32 UTC
    Maybe this answers your question:

    $val eq '2'
    String compare string value of $val with string '2'.

    $val == '2'
    Convert string '2' to number, and numerically compare with numeric value of $val

    $val == 2
    Compare numeric 2 with numeric value of $val

    If a string starts with a number, its numeric value will be that number. Consider the following examples:

    $ perl -e "print 'a' == 'b'"
    True because 0 == 0

    $ perl -e "print 'a' == '1b'"
    Not true because 0 != 1

    $ perl -e "print 'a' == 'b1'"
    True because 0 == 0


Re: eq vs. ==
by adrianh (Chancellor) on Jul 20, 2003 at 10:35 UTC


    print "eq" if "02" eq "2"; print "==" if "02" == "2";

    and many other variations on the theme. There are many strings that are "==" but not "eq" :-)

Re: eq vs. ==
by benn (Vicar) on Jul 20, 2003 at 12:24 UTC
    Following on from adrianh, also consider...
    print "==" if $a == ($b * $c);
    and of course, the potential confusion with..
    $a = "2.0"; print "eq" if $a eq "2"; # Nope print "==" if $a == 2; # Yup
    Basically, not all equality comparisons are string-based. In my 'perl mindset', if $a == "2", where the number is quoted, immediately begs the question as to which type of comparison is wanted...
    if $a eq "2" suggests that $a *generally* holds a non-numeric string...maybe part of something like foreach my $a (split(/\s+/,"my 1 markup 2 scheme where numbers 3 do 2 stuff")),whereas if $a == 2 suggests that $a *always* holds a number (and use warnings will then tell me if it doesn't for any reason).

    Cheers, Ben

Re: eq vs. ==
by tilly (Archbishop) on Jul 20, 2003 at 17:17 UTC
    Three random notes:
    1. One reason to use == rather than eq is so that you can get warnings if something non-numerical is used where you expect a number.
    2. One reason to use eq rather than == is that string conversions lose a few decimal places, so you put off hitting spurious inequalities due to floating-point rounding errors.
    3. Consider writing 2 == $val rather than $val == 2. It looks odd, but that way the common typo of = rather than == will give you an immediate compilation error rather than a nasty bug.

      Consider writing 2 == $val rather than $val == 2. It looks odd, but that way the common typo of = rather than == will give you an immediate compilation error rather than a nasty bug.

      I often see people recommending this, but I have yet to actually see it in practice.

      Is the = typo really so common that it warrants this kind of obfuscation? Not only does it "look odd," but it doesn't really make sense. You're not trying to find out if 2 equals the unknown, you want to know if the unknown equals 2--but in your code it's backwards. The truth is that I honestly can't remember the last time I made this mistake. No, I'm not bragging; my code has bugs too, and lots of them, but in my personal experience, the = typo really isn't a big problem. It's the type of mistake you make once, spend an enormous amount of time trying to debug, and upon discovering the deceptively simple cause, make sure you never make it again.

      Maybe the "constant == unknown" syntax is more useful in C or C++ where you've only got one equality operator, but in Perl, you have both == and eq, and you must actually think about which one to use for each conditional, thus you're less likely to make the mistake of typing = instead of ==.

      OT, but tilly, may I ask if you yourself use the "2 == $var" syntax?

        Yes, I use the 2 == $var syntax. And yes, I have caught several typos over the years by doing so. YMMV.

        As for how common the error is, my experience suggests that we tend to not have a good sense of the errors we make. A useful, painful, and humbling experience is to keep a log of every error of yours that you catch. Categorize them, then go back periodically to review them and think about how you could have prevented them up front.

        Odds are that you will find you make a lot more mistakes than you think you do. And they will be of different kinds than you think. (Me, I make more "careless, stupid" errors than I care to admit.)

        I use
        4 == func $a, $b

        because if I write it as:

        func $a, $b == 4

        I can never remember whether that's that calls func with the arguments $a and $b and compares that with 4, or whether it calls func with argument $a and the second argument true/false depending whether $b is 4 or not.


        I use that syntax and have also caught many more errors since doing that. It does look a tiny bit strange, but it really does help me catch some stupid typo errors.

        edit, removed the typo in 'typpo', which was rather ironic, no? :)

        How common is the '=' vs. '==' typo depends on which languages do you mix. If you only write in Perl and C/C++/C#/Java/JavaScript, then it's quite likely you'll not make this mistake. But if you have to write some VB or Pascal or ... then it can happen easily. OTOH, I more often write '==' in a condition in VB than '=' in Perl.

        Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
           -- Rick Osborne

        Edit by castaway: Closed small tag in signature

Re: eq vs. ==
by giulienk (Curate) on Jul 20, 2003 at 14:02 UTC
    Also somewhere in the documentation is noted that == is much cheaper than eq, so you may wanna use == whenever it makes sense.

    UPDATE: i guess there is some misunderstanding here. My line above saying "so you may wanna use == whenever it makes sense" must be read as "please use == when comparing something that should be a number, because using eq to compare two numbers is much less efficient". On the other side using == to compare two strings is less likely to give the result you want, so i didn't consider that case. Hope now it's clear.


      Can you provide a link? To compare a scalar numerically, Perl needs to check the flag that says it's okay to use as a number, convert it to a number, stow the number in the SV, set the okay to use as a number flag, and perform the comparison.

      Of course, to compare it as a string, it has to do the same sort of thing with the okay to use as a string flag.

      Besides all that, if mangling your program to use numeric equals really speeds it up, you're either a better programmer than anybody I've known or you should probably consider dropping to C. Please program for accuracy, not speed.

        Actually i think i read it in Mastering Algorithms with Perl even though i cannot find it right now.

        Anyway to wipe out your doubts you can try a benchmark:

        #!/usr/bin/perl use strict; use Benchmark qw(:all); cmpthese(10, { 'eq' => sub { for (my ($i, $j) = (0, 0); $i < 1_000_000; $i++) { $j++ if ($i % 3) eq 2; } }, '==' => sub { for (my ($i, $j) = (0, 0); $i < 1_000_000; $i++) { $j++ if ($i % 3) == 2; } }, }); __END__ Benchmark: timing 10 iterations of ==, eq... ==: 28 wallclock secs (27.91 usr + 0.00 sys = 27.91 CPU) @ 0 +.36/s (n=10) eq: 36 wallclock secs (36.16 usr + 0.01 sys = 36.17 CPU) @ 0 +.28/s (n=10) s/iter eq == eq 3.62 -- -23% == 2.79 30% --
        The test was run on my Powerbook G3 with Perl v5.8.0 built for powerpc-linux-thread-multi.

        I agree we shouldn't program for speed only, but here speed and good form comes from the same expression. Also you may note how my first post in this thread started out with "Also": it wasn't meant to be a comprehensive response to c's problem, but instead my 2 cents to what already said.


Re: eq vs. ==
by SyN/AcK (Scribe) on Jul 20, 2003 at 19:36 UTC

    Well, how about just making the context of how its being used more apparent. I mean, even in Perl where variables can be whatever we'd like them to be, sometimes it is nice to use them as you intend.