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

The following works as expected:
my $obj = MyObject->new; my $meth = 'dosomething'; $obj->meth;
The following not only does not work, it confuses the parser:
my $obj = MyObject->new; my %meth = (a => 'dosomething'); $obj->$meth{a};
This is a workaround I've found:
my $obj = MyObject->new; my %meth = (a => 'dosomething'); $obj->{ $meth{a} };
I am quite surprised by this. Can anyone explain to me what is happening here? Much appreciated. - Kurt

Replies are listed 'Best First'.
Re: Surprising quirk of method call parser
by kcott (Archbishop) on Nov 04, 2010 at 16:11 UTC

    On 5.12.0, that didn't work for me. Here's some tests:

    $ perl -wE 'sub meth { return (@_, q{A}); } my $o = bless {}; my $x = +q{meth}; say $o->$x;' main=HASH(0x10053ad8)A $ perl -wE 'sub meth { return (@_, q{A}); } my $o = bless {}; my %x = +(a => q{meth}); say $o->$x{a};' syntax error at -e line 1, near "$x{a" Execution of -e aborted due to compilation errors. $ perl -wE 'sub meth { return (@_, q{A}); } my $o = bless {}; my %x = +(a => q{meth}); say $o->{ $x{a} };' Use of uninitialized value in say at -e line 1. $ perl -wE 'sub meth { return (@_, q{A}); } my $o = bless {}; my %x = +(a => q{meth}); say $o->${\$x{a}};' main=HASH(0x10053ad8)A

    Your $obj->{ $meth{a} }; is valid syntax for a hashref based object; it's much the same as $hashref->{$key} (ditto for my $o->{ $x{a} }). However, I don't imagine it invoked a method.

    P.S. I think there's a typo in your first example. Should $obj->meth; be $obj->$meth;?

    -- Ken

      That's quite interesting. The example in question was running under 5.10. Two gold stars to you: one for recognizing that the code was dereferencing a hashref instead of calling a method, and the other for catching my typo.
Re: Surprising quirk of method call parser
by talexb (Chancellor) on Nov 04, 2010 at 15:47 UTC

    In Perl, braces are used to force the parser to evaluate those items first. You've solved the issue by putting braces around your hash access, so this means the parser was reading your code left to right, $obj->$meth followed by {a}, which it presumably hated.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      Alex, I can almost buy your explanation, but this code had "use strict", yet it didn't crap out with 'Global symbol "$a" requires explicit package name' (yes, I know that $a is special because of sort(); in the actual code, the variable had a different name (%Schema, to be precise), and was definitely declared as only a hash).