In Python I can use "==" to compare strings or numbers. But in Perl there are "==" and "eq". Using "==" with strings can lead to bugs. Why are there two operators? Is it safe to just always use "eq"?
-
4I don't think all "why" questions are "not constructive". This one, for example, isn't, as it implicitly asks for the difference of these operators. – glglgl Jun 20 '13 at 12:29
2 Answers
Perl has a different type system than Python. In Python, Strings and Numbers are different types. Perl has only Scalars.
To differentiate between string interpretation and numeric interpretation of a scalar, two sets of comparision operators are used.
E.g.
my $x = "foo";
my $y = 0;
$x == $y; # true, but warning
$x eq $y; # false
and
my $x = "1.0";
my $y = 1;
$x == $y; # true
$x eq $y; # false

- 57,091
- 2
- 89
- 149
As for the "why" part of your question: You have two different operators to do two different things. If you did not have two operators, you would never know for sure which of the two tests you did. As you can see in amon's answer the following is false:
"1.0" eq "1";
But on some occasions, you may want it to be true. In other words, the logic you are after is numerical comparison. On some other occasion, you may want stringwise comparison, in which case you don't want the above to be true.
Because Perl has no overt data types, the type of each individual scalar value is context dependent, like this:
if ($foo == 0) # $foo is converted to a number
if ($foo eq "0") # $foo is converted to a string
A feature of Perl is this context dependent conversion, and it can lead to strange behaviour when used wrong, such as this rather common problem:
if ("foo" == "bar") # true
Without the warnings pragma use warnings
turned on, this statement returns a false positive without any hint of a problem. The reason is that the context generated by the numerical equality operator ==
turns both strings into numbers, and that number is zero 0
. And of course, 0 == 0
is true. If either string had begun with a number, they would have been converted to that number instead.
-
I am trying to come up with a comparision where `$x == $y` is false, but `$x eq $y` is true, without using dualvars like `$!` or overloaded objects. Do you know if such a case exists? – amon Jun 20 '13 at 12:56
-
@amon That sounds impossible, since eq requires both parameters to be stringwise identical. In such a case, conversion would need to be done differently for == to return false, which is impossible in a single statement. – TLP Jun 20 '13 at 13:36