Given a variable containing a string that represents the name of a package, how do I call a specific subroutine of the package?
Here’s the closest thing I have figured out:
package MyPackage;
sub echo {
print shift;
}
my $package_name = 'MyPackage';
$package_name->echo('Hello World');
1;
The problem with this code is the subroutine is called as a class method; the package name is passed in as the first argument. I want to invoke the subroutine from the package name without a special first argument being implicitly passed in.
Perl method calls are just regular subroutines, which get the invocant as the first value.
If you want to call a subroutine without an invocant, you will need to call it differently.
The
canmethod returns a reference to the subroutine that would be called if it had been called on the invocant. The coderef can then be used separately.There are some caveats to using
can:canmay be overridden by the package, or any class from which it inherits.This may actually be the behaviour you’re looking for though.
Another approach is to use something called a symbolic reference.
Using symbolic references is usually not recommended. Part of the problem is that it is possible to accidently use a symbolic reference where you didn’t intend on using one. This is why you can’t have
use strict 'refs';in effect.This may be the simplest way to do what you want to do though.
If you don’t want to use a symbolic reference you could use the Stash.
The only problem with this is that you would have to split
$package_nameon::This isn’t that big of a problem though. After a quick look on CPAN you find Package::Stash.
(The Pure Perl version of Package::Stash uses symbolic references, not the Stash)
It’s even possible to make an alias of the subroutine/method, as if had been imported from a module that was using Exporter:
I would recommend limiting the scope of the alias though:
This is an exception, where you can use a symbolic reference with
strict 'refs'enabled.