如何在Perl中创建一个调度表,其中键包含空格,子例程接受数组参数?

时间:2009-11-23 05:25:59

标签: perl dispatch-table

这是我目前的想法,但我不知道如何派遣/执行它

my $key;
my @arraydata;

my %commandfunc{
"ab 1", \&func1(\@arraydata),
"ab 2", \&func2(\@arraydata,
"ab 3", \&func3(\@arraydata)
};

foreach $k (keys %commandfunc){
  if($something =~ /$k/){ #if $something match with a key string
        $key= $k;
        #some processing arraydata here;
    }

}
#dispatching??
my $command = $commandfunc{$key}->(\@arraydata);

请更正我的代码.. 非常感谢

3 个答案:

答案 0 :(得分:6)

使用常规parens(( ))初始化哈希,而不是大括号(哈希引用)。并且您使用列表赋值初始化哈希。所以第一部分应该是:

my %commandfunc = ( 
    "ab 1" => \&func1,
    "ab 2" => \&func2,
    "ab 3" => \&func3
);

=>运算符比使用逗号更漂亮,并且如果需要,还可以在左侧引用裸字。

我不确定你在循环中想要匹配的是什么($_来自哪里?)但是你可以这样做:

foreach my $k (keys %commandfunc) {
    if( $something =~ /$k/) {
        my $result = $commandfunc{$k}->( \@arraydata );
    }
}

答案 1 :(得分:5)

\&func1是子例程引用,但\&func1(\@arraydata)是对& func1调用返回的值的引用。请尝试改为:"ab 1" => \&func1, ...。 @arraydata的传递在您的调度代码中是正确的。

请注意,/$k/会使元字符变为。或*在正则表达式中有特殊效果;如果您不想这样做,请改为/\Q$k/。或者你可能只想要eq $k

答案 2 :(得分:4)

你是不是很清楚前面是否定义了@arraydata,以及这段代码执行的频率。直接翻译您的尝试将产生:

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}};
}

然而,这不是非常有效 - %commandfunc散列是用匿名子程序closures定义的,而我们只需将coderefs存储到没有参数绑定的原始subs,并传入一个数组后:

my %commandfunc = (
    "ab 1" => \&func1,
    "ab 2" => \&func2,
    "ab 3" => \&func3,
};

并将其称为:

my $result = $commandfunc{$match}->(@array);