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'
.
列出的变通方法可以解决此问题.