Given a package name $package
and a function name from within that package $function
, I can create a reference to that function:
my $ref = eval( "\\&${package}::${function}" );
As a complete example:
#!/usr/bin/perl -w
use strict;
package foo;
sub func()
{
print "foo::func\n";
}
package main;
my $package = "foo";
my $function = "func";
my $ref = eval( "\\&${package}::$function" );
$ref->();
I do not particularly like that eval()
in there and wonder if the same result could be achieved without eval()
?
CodePudding user response:
All you need is this:
my $ref = \&{ "${package}::$name" };
or
my $ref = \&{ $package . "::" . $name };
Using an expression producing the name of a variable where a variable name is expected is called a symbolic reference. These are usually forbidden by use strict;
(specifically use strict qw( refs );
), but \&
is exempt.
CodePudding user response:
Using strings to refer to subroutines is seldom the right way. If you are doing it this way, you are most likely doing something wrong. You can use a code reference to store a reference to a function, in a scalar or hash. The hash allows you to correctly look up code references via string inputs.
use strict;
use warnings;
package foo;
sub func() {
print "inside foo::func (@_)\n";
}
package main;
# use a direct reference, in a scalar variable
my $ref = \&foo::func;
$ref->(1,2,3);
# ...or in a hash
my $pack = "foo";
my $func = "func";
my %table = ( foo => { func => \&foo::func } );
$table{$pack}{$func}->(qw(a b c));
Output:
inside foo::func (1 2 3)
inside foo::func (a b c)