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);
加载中,请稍侯......
精彩评论