在Perl中调用子例程的非标准方式

vai*_*002 3 perl subroutine

我正在尝试一种在Perl脚本中调用子例程的不同方法.

我有一组功能如下:

sub Testcase_CheckStatus {
    print "TestCase_CheckStatus called\n";
}
Run Code Online (Sandbox Code Playgroud)

然后我用"CheckStatus"这样的键遍历Perl哈希:

while (my ($k, $v) = each %test_cases) {
    print "TestCase_$k","\n";
    Testcase_$k();
}
Run Code Online (Sandbox Code Playgroud)

基本上,我想在解析哈希的键时调用上面的函数Testcase_CheckStatus,但是我收到了这个错误:

无法通过包"CheckStatus"找到对象方法"Testcase_"(也许你忘了在./main.pl第17行加载"CheckStatus"?)

我该怎么做才能解决这个问题?有没有其他方法可以做同样的事情?

w.k*_*w.k 13

另一种方式:

use 5.010;
use warnings;
use strict;


my $testcases = {
    test_case_1 => sub {
        return 1 * shift();
    },
    test_case_2 => sub {
        return 3 * shift();
    },
    test_case_3 => \&SomeSub,
};

for (1 .. 3) {
    say $testcases->{ 'test_case_' . $_ }(7);
}


sub SomeSub {
    return 5 * shift();
}
Run Code Online (Sandbox Code Playgroud)


mtt*_*trb 6

以下应该可以让你做你想做的事:

while (my ($k, $v) = each %test_cases) {
    print "TestCase_$k","\n";
    &{"Testcase_$k"}();
}
Run Code Online (Sandbox Code Playgroud)

但是,如果strict正在使用,这将不起作用.如果您正在使用strict,则需要no strict在while循环内部,例如:

while (my ($k, $v) = each %test_cases) {
    no strict 'refs';

    print "TestCase_$k","\n";
    &{"Testcase_$k"}();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果程序员不小心从外部提供的数据,这是单一的并且倾向于可能的命令注入.我不能推荐它. - wk.的答案显示了一个调度表; 在大多数情况下应该使用该解决方案. (10认同)
  • "没有严格......"几乎等于"让我们做错误的方式".我的意思是,在许多情况下它可以用作黑客,但通常它表明正在采取错误的方法.如果你必须这样做,但至少在它周围建立一连串的警告评论. (2认同)