Do yourself a favour and implement a dispatch table. This additional
level of indirection may seem a maintenance burden, but it will sure
pay off in the long run. You will know exactly when and why it's failing,
and you will also minimize the risk of malicious code injection.
Here's a sketch:
#!/usr/bin/perl
use strict;
use warnings;
use Carp;
{
my %actions =
(
one => \&one,
two => \&two,
three => \&three
);
sub dispatch {
# detect early all invalid arguments
my @invalid = grep {!exists($actions{$_})} @_;
if (@invalid) {
local $" = ', ';
croak("invalid action(s): (@invalid)");
# or the death spell of your choice
}
# else {
for (@_) {
# call $actions{$_}->(...), for example:
$actions{$_}->("<<$_>>");
}
# }
}
}
# stub subs generator for exemplification only
BEGIN {
eval 'sub ' . $_ . q{ {
local $" = ', ';
print "sub [@{[(caller 0)[3]]}] with args: (@_)\n";
}} for qw/one two three/;
}
dispatch(qw/one two three/);
dispatch(qw/three two one kaboom silence/);
Don't just cut and paste my code. I don't have the slightest idea
about what you're trying to do with your program. The code above is
not substitute for your own judgement.
P.S.
If you decide to use symbol tables instead of plain hashes for lookup, as other
people have suggested in this thread, try to use a separate namespace
for this purpose and not main::. "Whitelisting" is
important from a security perspective.