perl - Perl:常量和编译时与运行时哈希查找?
问题描述
在 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}->();
请注意,在 中STATE_1
,我正在尝试调用该STATE_2
函数。
但是,在运行时我得到这个:
Can't use an undefined value as a subroutine reference at ./self-reference-hash.pl line 15.
这表明该$fsm{STATE_2}->(@_);
行STATE_1
未定义。事实上,在这条线第一次出现的时候,这个STATE_2
函数还没有定义,但我指望哈希查找在运行时被解析。
如果我改为替换$fsm{STATE_2}->(@_);
为my $tmp = STATE_2; $fsm{$tmp}->(@_);
then 它会按预期工作,这似乎很hacky。
有没有更清洁的方法来做到这一点?
解决方案
这个问题的根源实际上在Perl 的文档 aboutconstant
中进行了解释,它不是关于运行时与编译时的关系,而是关于 Perl 在某些情况下神奇地引用了裸词:
如果您在自动引用裸词的上下文中使用常量(对于任何子例程调用都是如此),您可能会遇到麻烦。例如,您不能说
$hash{CONSTANT}
因为CONSTANT
将被解释为字符串。使用$hash{CONSTANT()}
or$hash{+CONSTANT}
防止裸词引用机制启动。类似地,由于 => 运算符在其左侧立即引用裸词,因此您必须说CONSTANT() => 'value'
(或简单地使用逗号代替大箭头)而不是CONSTANT => 'value'
.
列出的解决方法可解决该问题。
推荐阅读
- swift - SFSpeechRecognizer 能用拼音返回结果吗?
- c++ - 具有依赖和文件写入的 c++ 单元测试
- python-3.x - 在字典中找到最大的元素索引?
- python-3.x - 如何在一个函数中将 matplotlib 图表与 networkX 图表结合起来?
- python - ErrorSchemaValidation 对电子邮件主题的多个过滤器查询(由于“已超过最大读取深度 (32)”)
- java - 在 Java 中创建的每个新对象将对象实例变量加一
- database - 如何在不复制数据的情况下克隆 sqlite 数据库结构(Windows)
- reactjs - 为 Twitch 扩展反应 redux 操作
- java - MongoDB权限更改?
- cookies - 当我尝试执行此方法时出现错误 app.UseCookieAuthentication(); 在 MVC (.net 5) 中