Calling Methods Indirectly
Problem
You want to call a method by a name that isn’t known until run time.
Solution
Store the method name as a string in a scalar variable and use it where you would use the real method name to the right of the arrow operator:
$methname = "flicker"; $obj->$methname(10); # calls $ob->flicker(10); # call three methods on the object, by name foreach $m ( qw(start run stop) ) { $obj->$m(); }
Discussion
Sometimes you need to call a method whose name you’ve stored
somewhere. You can’t take the address of a method, but you can
store its name. If you have a scalar variable
$meth
containing the method name, call the method
on an object $crystal
with
$crystal->$meth()
.
@methods = qw(name rank serno); %his_info = map { $_ => $ob->$_() } @methods; # same as this: %his_info = ( 'name' => $ob->name(), 'rank' => $ob->rank(), 'serno' => $ob->serno(), );
If you’re desperate to devise a way to get a method’s
address, you should try to rethink your algorithm. For example,
instead of incorrectly taking \$ob->method()
,
which simply applies the backslash to that method’s return
value or values, do this:
my $fnref = sub { $ob->method(@_) };
Now when it’s time to call that indirectly, you would use:
$fnref->(10, "fred");
and have it correctly really call:
$obj->method(10, "fred");
This works even if $ob
has gone out of scope. This
solution is much cleaner.
The code reference returned by the UNIVERSAL
can()
method should probably not be used as an indirect method call. That’s because you ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.