I have realised (the hard way) that operator eq
gives a fatal runtime error when one of the operand is an object with overloaded stringification.
Here is a minimal example:
my $test = MyTest->new('test');
print 'yes' if $test eq 'test';
package MyTest;
use overload '""' => sub { my $self = shift; return $self->{'str'} };
sub new {
my ( $class, $str ) = @_;
return bless { str => $str }, $class;
}
The result of running this is:
Operation "eq": no method found,
left argument in overloaded package MyTest,
right argument has no overloaded magic at ./test.pl line 7.
My expectation from reading perlop would be that string context is forced on both operands, firing the stringification method in $test
, then the resulting strings are compared. Why doesn't it work? What is actually hapenning?
The context in which I had this problem was in a script that uses both autodie
and Try::Tiny
. In the try
block, I die
with some specific messages to be caught. But in the catch
block, when I test for whether $_ eq "my specific message\n"
, this gives a runtime if $_
is an autodie::exception
.
I know I will have to replace $_ eq "..."
with !ref && $_ eq "..."
, but I would like to know why.
"$test" eq 'test'
– Schaeffereq
comparison doesn't actually force$test
to be stringified, it just use string compare on its arguments. – Schaeffer