How do I create a dispatch table in Perl with key contain whitespace and the subroutine accepting an array parameter?
Here's my current thinking, but I dont know how to dispatch/execute it
my $key; my @arraydata; my %commandfunc{ "ab 1", \&func1(\@arraydata), "ab 2", \&func2(\@arraydata, "ab 3", \&func3(\@arraydata) }; foreach $k (keys %commandf开发者_JS百科unc){ if($something =~ /$k/){ #if $something match with a key string $key= $k; #some processing arraydata here; } } #dispatching?? my $command = $commandfunc{$key}->(\@arraydata);
Please correct my code.. Thanks alot
Hashes are initialized with regular parens ( ( )
), not curly brackets (those are for hash references.) And you initialize a hash with a list assignment. So the first part should be:
my %commandfunc = (
"ab 1" => \&func1,
"ab 2" => \&func2,
"ab 3" => \&func3
);
The =>
operator is a little prettier than using a comma and has the added benefit of quoting barewords on the left side, if necessary.
I'm not sure what you're trying to match in your loop (where does $_
come from?) But you can do something like this:
foreach my $k (keys %commandfunc) {
if( $something =~ /$k/) {
my $result = $commandfunc{$k}->( \@arraydata );
}
}
\&func1
is a subroutine reference, but \&func1(\@arraydata)
is a reference to the value returned by a call to &func1. Try instead just: "ab 1" => \&func1, ...
. The passing of @arraydata is correct in your dispatch code.
Note that /$k/
will make metacharacters like . or * have their special effect in the regex; if you don't want that, do /\Q$k/
instead. Or possibly you want just eq $k
?
You weren't really clear whether @arraydata
was defined up front or not, and how often this code would be executed. A direct translation of your attempt would yield:
my %commandfunc = (
"ab 1" => sub { func1(@arraydata) },
"ab 2" => sub { func2(@arraydata) },
"ab 3" => sub { func3(@arraydata) },
};
if (my ($match) = grep { $_ eq $key } keys %commandfunc)
{
my $result = &{$commandfunc{$match}};
}
However this is not very efficient - the %commandfunc
hash is being defined with anonymous subroutine closures, when we could instead just store coderefs to the original subs with no arguments bound, and pass in an array later:
my %commandfunc = (
"ab 1" => \&func1,
"ab 2" => \&func2,
"ab 3" => \&func3,
};
and call it like this:
my $result = $commandfunc{$match}->(@array);
精彩评论