我正在使用一个模块,它利用一些原型来允许代码块。例如:
sub SomeSub (&) { ... }
由于原型只在编译时解析有效,因此如果模块在编译时未被解析,我希望发出警告甚至是致命错误。例如:
require MyModule; # Prototypes in MyModule won't be parsed correctly
有没有一种方法可以在Perl中检测某个东西是在编译时还是运行时/阶段执行的?
我正在使用一个模块,它利用一些原型来允许代码块。例如:
sub SomeSub (&) { ... }
由于原型只在编译时解析有效,因此如果模块在编译时未被解析,我希望发出警告甚至是致命错误。例如:
require MyModule; # Prototypes in MyModule won't be parsed correctly
如果您正在运行Perl 5.14或更高版本,则可以使用特殊的${^GLOBAL_PHASE}
变量,其中包含当前编译器状态。以下是一个示例。
use strict;
use warnings;
sub foo {
if ( ${^GLOBAL_PHASE} eq 'START' ) {
print "all's good\n";
} else {
print "not in compile-time!\n";
}
}
BEGIN {
foo();
};
foo();
输出:
all's good
not in compile-time!
INIT {}
块。它应该只在模块在 BEGIN 中加载时起作用(例如使用 use
)。 - kobame在5.14版本之前(或之后),您可以执行以下操作:
package Foo;
BEGIN {
use warnings 'FATAL' => 'all';
eval 'INIT{} 1' or die "Module must be loaded during global compilation\n";
}
但这个(以及${^GLOBAL_PHASE}
)并不能完全检查您想要知道的内容,即包含use/require语句的代码是正在编译还是运行。
require
而不是use
时,我只得到一个警告(当然启用了警告),警告信息为:Too late to run INIT block at (eval 11) line 1.
,但它并没有真正失败,也从未到达die调用(退出代码为0)。 - Francisco Zarabozoeval
在任何一个版本上都没有失败。 - Francisco Zarabozo
require Your::Module; printf "Your::Module %s installed\n", Your::Module->VERSION;
。这可以在设置或诊断脚本中完成,以报告应用程序所有先决条件的安装版本。 - tobyinkuse module
,那么“module”中的所有内容都会在编译时解析,包括你刚才使用的示例。无论如何,这与我提出的场景无关,我的场景是确保原型在全局编译时被正确解析,因为在此之后,就没有其他方法了。 - Francisco Zarabozorequire Your::Module; &Your::Module::SomeSub(sub { ... });
如果人们使用您的模块不寻常,为什么不假设他们知道自己在做什么呢?我写了很多模块 带有 编译-时 效果,但从未像这样向它们添加警告。require
与use
并不做同样的事情,但这并不意味着它毫无用处。 - tobyink