perl - 如何阻止代码在编译器阶段运行?
问题描述
这个问题需要了解编译器阶段与BEGIN
块。来自编程 Perl:第 3 版 - 第 467 页
了解编译阶段和编译时间之间以及运行阶段和运行时间之间的区别也很重要。一个典型的 Perl 程序有一个编译阶段,然后是一个运行阶段。“阶段”是一个大范围的概念。但是编译时间和运行时间是小规模的概念。给定的编译阶段主要做编译时的事情,但它也通过
BEGIN
块做一些运行时的事情。一个给定的运行阶段主要做运行时的事情,但它可以通过像eval STRING
.
让我们举一个非常简单的例子
sub complex_sub {
die 'code run';
}
sleep 5;
print 'good';
use constant FOO => complex_sub();
如果上面是按原样运行的,那么complex_sub
从用户的角度来看是在编译器阶段运行的。但是,只要稍作修改,我就可以拥有..
# Bar.pm
package Bar {
use constant FOO => main::complex_sub();
}
# test.pl
package main {
sub complex_sub {
die 'code run';
}
sleep 5;
print 'good';
require Bar;
}
上面的代码complex_sub
是在执行阶段运行的。无论如何从complex_sub
启用顶部语法但禁止底部语法的角度来区分这两种情况。
解决方案
使用${^GLOBAL_PHASE}
变量。它在第一种情况下包含“START”,但在第二种情况下包含“RUN”。
# RUN
perl -wE'say ${^GLOBAL_PHASE}'
# START
perl -wE'BEGIN {say ${^GLOBAL_PHASE}}'
# RUN
perl -wE'eval q{BEGIN {say ${^GLOBAL_PHASE}}}'
有关详细信息,请参阅perlvar。
推荐阅读
- c - 从完整的响应字符串中解析 AT 命令的有效负载
- python - Python:从 BeautifulSoup 中查找元素
- panda3d - 在 Panda3D 中将过滤器类型设置为纹理时出现访问冲突错误
- visual-studio - Acumatica 和 Visual Studio 2022 兼容性
- c# - 如何在 Edge 上使用 Selenium Webdriver/xUnit/c# 加载文件?它适用于其他浏览器
- sql - 我们是否曾经打算从 Sharepoint 列表中写入 SQL 查询?
- airflow - 气流 dag conf 值
- scala - Scala 3 上下文抽象与重载冲突
- java - 为什么 java.net.useSystemProxies 似乎不起作用?
- asp.net - 如何在 APS.net 网络表单中添加新行项目并提交到数据库