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:
This can be made by accessing the function via the symbol table. Note that this needs no strict 'refs'
, which can be restricted to a block though:
my $package = "foo";
my $function = "func";
my $ref = do {
no strict 'refs';
*{"${package}::${function}"};
};
$ref->();
Example:
getref("Foo","bar")->(); # Foo::bar
getref("Bar","foo")->(); # Bar::foo
sub getref {
my ($pkg,$sub) = @_;
no strict 'refs';
return *{"${pkg}::${sub}"};
}
package Foo;
sub bar { print "Foo::bar\n" }
package Bar;
sub foo { print "Bar::foo\n" }
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)