http://www.perlmonks.org?node_id=996787


in reply to Invoking a method whose name is computed

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!

Replies are listed 'Best First'.
Re^2: Invoking a method whose name is computed
by afoken (Chancellor) on Oct 02, 2012 at 05:43 UTC

    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
Re^2: Invoking a method whose name is computed
by tobyink (Canon) on Oct 02, 2012 at 16:30 UTC

    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'