Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Invoking a method whose name is computed

by Anonymous Monk
on Oct 01, 2012 at 23:32 UTC ( #996764=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Quick question. Assume the following variable values:

my $meth = "prefix_foo"; my $x = "foo";

Perl allows me to do this:

Some::Class->$meth;

but not this:

Some::Class->"prefix_$x";

My workaround at the moment is:

Some::Class->${\("prefix_$x")};

Is there a more straightforward version? Besides the more obvious two-statement version, that is.

my $tmp = "prefix_$x"; Some::Class->"prefix_$tmp";

Comment on Invoking a method whose name is computed
Select or Download Code
Replies are listed 'Best First'.
Re: Invoking a method whose name is computed
by AnomalousMonk (Abbot) on Oct 02, 2012 at 02:10 UTC
    Is there a more straightforward version?

    I don't know if you will consider it more straightforward, but the  can() universal method can be used here (see The UNIVERSAL Class in perlobj). As the original example is a class method call, argument passing is, well, straightforward. Had it been an object method, the object reference would need to be passed explicitly as the first argument. (Update: See the reply of afoken for the correct way to invoke with class name or object reference.) Also be aware that if the method does not exist,  can() returns undef.

    >perl -wMstrict -le "use 5.014; ;; package Foo { sub bar_baz { print 'i am bar_bazing! ', @_; } } ;; my $x = 'baz'; Foo->can(qq{bar_$x})->('Hooray!'); " i am bar_bazing! Hooray!

      You invoke Foo::bar_baz as function, not as method. For a method call, the object / class name implicitly added by perl is missing, so you have to add it manually:

      Class->can("prefix_$name")->(Class,'first argument'); $object->can("prefix_$name")->($object,'first argument');

      Hardly DRY. I prefer "wasting" a variable for composed method names:

      my $method="prefix_$name"; Class->$method('first argument'); $object->$method('first argument');

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        An advantage of the "wasted variable" (I prefer to think it is an "intelligently used variable") is that you can perform a little validation:

        my $object = bless {hi => 'hello'}; for my $suffix ('x', 'y') { my $method = $object->can("prefix_$suffix"); $object->$method() if $method; } sub prefix_x { my ($self) = @_; print "$self->{hi} world\n"; }

        Update: elaborate code to better show intent.

        True laziness is hard work

      A pretty good solution, but doesn't work for autoloaded methods unless the developer has been conscientious and overloaded can correctly.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Invoking a method whose name is computed
by tobyink (Abbot) on Oct 01, 2012 at 23:43 UTC

    Not really.

    You could potentially use Object::Tap...

    use 5.010; use Object::Tap -package => 'UNIVERSAL'; sub Foo::bar { say "Foo::bar"; } Foo->tap(join 'a', 'b', 'r');
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: Invoking a method whose name is computed
by runrig (Abbot) on Oct 01, 2012 at 23:38 UTC
    Is there a more straightforward version? Besides the more obvious...

    No.

Re: Invoking a method whose name is computed
by Anonymous Monk on Oct 01, 2012 at 23:33 UTC

    Sorry, the last part should've been:

    my $tmp = "prefix_$x"; Some::Class->$tmp;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://996764]
Approved by davido
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2015-07-30 03:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (269 votes), past polls