2012-05-21 17 views
3

我正在尝试以不同的方式调用Perl脚本中的子例程。在Perl中调用子例程的非标准方式

我有一组功能如下:

sub Testcase_CheckStatus { 
    print "TestCase_CheckStatus called\n"; 
} 

然后我遍历一个Perl的哈希值与像“的checkStatus”键:

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

基本上,我想调用的函数Testcase_CheckStatus像上面一样解析哈希键,但我得到这个错误:

Can't locate object method "Testcase_" via package "CheckStatus" (perhaps you forgot to load "CheckStatus"?) at ./main.pl line 17

什么可以我会纠正这个问题吗?有没有其他方法可以做到这一点?

+3

注意,这下是有原因的“严格”模式不允许的。在运行时建立函数或变量名是危险和脆弱的。另一方面,wk的解决方案(使用匿名函数的散列)提供了完全相同的结果,既安全又完美。 – wazoox

+1

重要背景阅读:“为什么使用变量作为变量名称是愚蠢的”([第1部分](http://perl.plover.com/varvarname.html),[第2部分](http:// perl)。 ,以及[第3部分](http://perl.plover.com/varvarname3.html)),作者是Mark Dominus,出色的[* Higher Order Perl *](http:// hop.perl.plover.com/)。 –

回答

6

下面应该让你做你想要的:

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

但是,如果strict在使用中这是行不通的。如果你正在使用strict你将需要一个no strict while循环中,例如:

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

    print "TestCase_$k","\n"; 
    &{"Testcase_$k"}(); 
} 
+10

如果程序员不小心处理外部提供的数据,这是单向的,并且可能会有命令注入。我不能推荐它。 - wk。的答案显示了发送表;应该在大多数情况下使用该解决方案。 – daxim

+2

“没有严格的......”几乎等于“让我们做错误的方式”。我的意思是,它可以在许多情况下用作黑客,但通常表示正在采取错误的方法。如果你必须这样做,但至少要在它周围建立一个警戒评论。 –

+1

你们两个都是对的,我不会这样做,但是它直接回答了OP如何在一个字符串中给函数名部分调用一个函数的问题。 – mttrb

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(); 
} 
+0

它通常被称为“调度表”。 – choroba