Let say I have one array that contains all subroutine name and I want to call all one by one.
foreach $sub (@arr){
print "Calling $sub\n";
#---How to call $sub?----
&$sub; ## will not work
}
Let say I have one array that contains all subroutine name and I want to call all one by one.
foreach $sub (@arr){
print "Calling $sub\n";
#---How to call $sub?----
&$sub; ## will not work
}
You want to do that using code references.
foreach my $sub (@arr)
{
$sub->();
}
where @arr
contains scalars such as
my $rc = sub { print "Anonymous subroutine\n" };
or
sub func { print "Named sub\n" }
my $rc = \&func;
You can manipulate these scalars as you would any other, to form your array. However, it is more common and useful to use them as values in a hash, creating a dispatch table.
See perlref and perlsub, and (for example) this post and links in it for comments and details.
Your code is correct in general, but you need to turn off
strict 'refs'
to make Perl allow you to use variable content as code refs.The output here is:
I've also added parenthesis
()
after the call. That way we pass no arguments to%$sub
. If we do not those, the@_
argument list of the current subroutine will be used.However, you should probably not do this. Especially if
@arr
contains user input, this is a big problem. Your user can inject code. Consider this:Now we get the following output:
Oops. You don't want to do this. The
die
example is not very bad, but like this you could easily call code in some different package that wasn't intended.It's probably better to make a dispatch table. There is a whole chapter about those in Higher Order Perl by Mark Jason Dominus, which you can download for free on his website.
It basically means you put all the subs into a hash as code references, and then call those in your loop. That way you can control which ones are allowed.
This outputs: