使用perl动态调用sub

时间:2014-06-12 05:34:33

标签: perl dynamic

我有4个子rountines(sub room1 {do stuuf ...},sub room2 {do stuff ...},sub room3 {do other stuff ...})将在例程中执行不同的操作。

我想要做的是能够根据变量名称动态调用例程。

例如,

if ($currentRoom == 1) { &room1; } 
if ($currentRoom == 2) { &room2; }
if ($currentRoom == 3) { &room3; }

我宁愿做的只是使用$ currentRoom作为& room之后的值来调用正确的子例程。类似于& room {$ currentRoom};

可以这样做,如果是这样,我怎样才能做到这一点。

3 个答案:

答案 0 :(得分:16)

创建一个与房间号相关的哈希值到子例程引用:

my %room_actions = (
    1 => \&room1,
    2 => \&room2,
    3 => \&room3,
);

if ($room_actions{$currentRoom}) {
    $room_actions{$currentRoom}->();
} else {
    die "room doesn't exist: $currentRoom";
}

答案 1 :(得分:1)

你可以试试这个:

use strict;
use warnings;

sub test1 {print 1}
sub test2 {print 2}
my $test = 1;
{ # naked block, to make no strict 'refs' not global
  no strict 'refs';
  &{'test'.$test}();
}

输出:

1

但要做好准备,如果您尝试访问不存在的子代码(例如上面代码中的3),则会收到警告:

Undefined subroutine &main::test3 called at test.pl .....

答案 2 :(得分:1)

这已经差不多两年了,但是在我进行了一些相关搜索之后我就落到了这里,我对这个解决方案的缺乏感到震惊:

__PACKAGE__->can('room' . $currentRoom)->();

您还可以添加一些自定义错误检查:

if (my $sub = __PACKAGE__->can('room' . $currentRoom)) {
   $sub->();
}

这是一种快速而肮脏的调度表,使用can代替散列访问但不放弃任何安全网。