Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

This question already has an answer here:

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
}
share|improve this question

marked as duplicate by mob perl Jan 5 at 16:11

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
(\&$name)->(@args) – ikegami Jan 5 at 14:38

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.

use strict;
use warnings;

sub foo { print "foo" }
sub bar { print "bar" }

my @arr = qw/foo bar/;
foreach my $sub (@arr) {
    no strict 'refs';
    print "Calling $sub\n";

    &$sub();
}

The output here is:

Calling foo
fooCalling bar
bar

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:

my @arr = qw/CORE::die/;

Now we get the following output:

Calling CORE::die
Died at /home/code/scratch.pl line 1492.

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.

use strict;
use warnings;

sub baz { print "baz" }

my %dispatch = (
    foo => sub { print "foo" },
    bar => sub { print "bar" },
    baz => \&baz,
);

my @arr = qw/foo bar baz wrong_entry/;
foreach my $sub ( @arr ) {
    die "$sub is not allowed" 
        unless exists $dispatch{$sub};

    $dispatch{$sub}->();
}

This outputs:

foobarbaz
wrong_entry is not allowed at /home/code/scratch.pl line 1494.
share|improve this answer
1  
I gave the man a fish, you taught him how to fish. +1 – Zaid Jan 5 at 10:00
1  
@Zaid oh, there are two more answers. I didn't see them yet. I was just busy hacking down half a blog post in here again... :D – simbabque Jan 5 at 10:00
    
HI simbabque. Thanks. I was not knowing that. In my case users are not providing subroutine name in arguments but good info. – Raj Jan 5 at 10:03
    
@Zaid I assumed the OP does not have use strict because there was no my sub in the loop. In that case, the OP's code works. With strict turned on however, strict 'refs' needs to be disabled. – simbabque Jan 5 at 10:07
    
Am I getting downvoted because it's too much text? – simbabque Jan 5 at 10:36

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 for creating code references, and this post may help as well.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.