Joh*_*aye 4 perl hash constants
在Perl 5.26中,基于常量的哈希查找似乎在编译时解析,而不是运行时.如何强制它在运行时解决?
考虑以下简化的测试用例,从我试图编写的基于哈希的状态机中归结,其中键是状态标识符,值是状态函数.
use constant {
STATE_1 => 1,
STATE_2 => 2,
};
my %fsm;
%fsm = (
STATE_1, sub {
$fsm{STATE_2}->(@_);
return STATE_2;
},
STATE_2, sub {
return STATE_1;
}
);
my $state = STATE_1;
$state = $fsm{$state}->();
Run Code Online (Sandbox Code Playgroud)
请注意STATE_1,我正在尝试调用该STATE_2函数.
但是,在运行时我得到这个:
Can't use an undefined value as a subroutine reference at ./self-reference-hash.pl line 15.
Run Code Online (Sandbox Code Playgroud)
这表示该$fsm{STATE_2}->(@_);行STATE_1未定义.事实上,在这条线第一次出现的时候,该STATE_2功能没有定义还没有,但我对哈希查询计数在运行时得到解决.
如果我替换$fsm{STATE_2}->(@_);为my $tmp = STATE_2; $fsm{$tmp}->(@_);然后它按预期工作,这似乎是hacky.
有更清洁的方法吗?
Joh*_*aye 13
这个问题的根源实际上是在Perl的doc中constant解释的,它不是关于运行时与编译时的关系,而是关于Perl在某些情况下神奇地引用了裸字:
如果在自动引用裸字的上下文中使用常量,则可能会遇到麻烦(对于任何子例程调用都是如此).例如,你不能说
$hash{CONSTANT}因为CONSTANT将被解释为一个字符串.使用$hash{CONSTANT()}或$hash{+CONSTANT}防止裸字引用机制被踢入.同样,由于=>运算符立即向其左侧引用一个裸字,您必须说CONSTANT() => 'value'(或者仅使用逗号代替大箭头)而不是CONSTANT => 'value'.
列出的变通方法可以解决此问题.