Perl 通过子过程的引用来调用子过程
文章目录
假如我有一个子过程,定义如下:
sub test_sub { print "test"; }
我又有一个变量:
$test = "test_sub";
这个 $test 的值刚好就是上面子过程的名称。既然我通过 $test 知道了这个子过程名称,我可以通过 $test 达到调用这个子过程的目的吗?也就是说,我让用户从命令行里输入一个子过程的名称,然后就可以根据这个名称来调用相对应的子过程。
方法一,直接根据用户输入的子过程名来调用该子过程。
完整的例子代码如下:
use warnings; no strict 'refs'; sub test_sub { print "test"; } $test = "test_sub"; $test->(); &{$test}(); #anyway to invoke the subroutine
这里要注意,需要用
no strict 'refs';
这个语句,否则脚本不能运行,Perl 解释器会提示类似于下面的错误:
Global symbol “$test” requires explicit package name at test2.pl line 10.
方法二,更常规的做法是专门用一个起分派作用的散列,根据用户输入的请示而调用相应的子过程。例如下面的 %dispatcher 就起到了绑定识别标记与相应子过程引用的作用,通过这个唯一的标记 (key),我们可以很容易地找到对应的子过程引用。
my %dispatcher = ( sub_test => sub { print "test" }, );
然后可以用和方法一相同的语法来调用这个子过程:
$dispatcher{$sub_name}->();
下面是方法二的一个完整的例子:
use warnings; use strict; sub test_sub { print "test\n"; } sub test_other { print "test other\n"; } my %dispatcher = ( "test_sub" => \&test_sub, "test_other" => \&test_other, ); print "\nPlease enter the test case you want to test:\n"; while( my $cmd = <> ) { chomp($cmd); $dispatcher{$cmd}->() if exists $dispatcher{$cmd}; }
当然,方法二要比方法一优秀得多,它可以避免用户输入错误的子过程名而导致一系列的麻烦。
文章作者 cookwhy
上次更新 2009-09-21