Why does this snippet complain about 'Can't locate object method "this" via package "t"' and not just fail to run?

Viewed 260

Found a typo bug in an old script, but I don't understand how this line passes a perl -cw:

$ perl -w -e 'my $t = "t"; this{$t} '
Can't locate object method "this" via package "t" (perhaps you forgot to load "t"?) at -e line 1.
$ perl -w -e 'my $t; this{$t} '
Can't call method "this" on an undefined value at -e line 1.

The bug is the missing $ sigil for a hash %this But why does perl think I'm trying reference an object here?

2 Answers
$ perl -MO=Deparse -e 'this{$t}'
this {
    $t
} ;

$ perl -we 'sub this{42} ; this{$t}'
Name "main::t" used only once: possible typo at -e line 1.
Odd number of elements in anonymous hash at -e line 1.
Use of uninitialized value $t in anonymous hash ({}) at -e line 1.

$ perl -we 'sub this{42} ; this{42,43}'
# No output

Perl is parsing {$t} as an anonymous hash reference and expecting this to be a subroutine that can accept the reference as an argument. After Perl fails to find a subroutine named this, it tries to see if the construction can be parsed as indirect object syntax. Namely, it identifies the object type of {$t} and looks for a method this in that object type's namespace. This is the last resolution method the parser tries, so when it fails you get the error message from that section of the parser.

This is the METHOD OBJECT indirect object syntax. this{$t} is like this {$t} or this $t or $t->this.

For a simple scalar variable invocant, the {} are optional, but if your invocant were some other expression, e.g. $h{$t}, this $h{$t} does not work; it has to be $h{$t}->this or this { $h{$t} }.

Related