我有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};
可以这样做,如果是这样,我怎样才能做到这一点。
答案 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
代替散列访问但不放弃任何安全网。