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?
-c
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
Liz | [reply] [d/l] [select] |
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" :-) | [reply] [d/l] |
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 | [reply] [d/l] [select] |
Re: eq vs. ==
by tilly (Archbishop) on Jul 20, 2003 at 17:17 UTC
|
Three random notes:
- 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.
- 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.
- 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.
| [reply] [d/l] [select] |
|
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?
| [reply] |
|
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.)
| [reply] [d/l] |
|
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.
Abigail | [reply] [d/l] [select] |
|
|
| [reply] |
|
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.
Jenda
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
| [reply] |
|
|
|
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.
$|=$_="1g2i1u1l2i4e2n0k",map{print"\7",chop;select$,,$,,$,,$_/7}m{..}g
| [reply] |
|
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.
| [reply] |
|
#!/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.
$|=$_="1g2i1u1l2i4e2n0k",map{print"\7",chop;select$,,$,,$,,$_/7}m{..}g
| [reply] [d/l] |
|
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.
| [reply] |
|
|