开发者

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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜