Perl 中的 BEGIN,CHECK,INIT& END 块



根据我对Perl代码中这些特殊函数的理解,BEGIN和CHECK块在编译阶段运行,而INIT和END块在实际执行阶段运行。

我可以理解在实际的Perl代码(Perl库)中使用这些块,但在模块中使用它们呢?这可能吗?

因为当我们使用use <Module-name>时,模块是编译的,所以实际上BEGIN和CHECK块是运行的。但是INIT和END块将如何运行,因为我认为模块代码不是真正意义上的运行。我们只使用模块内部的某些功能。

;通过use加载的包中的特殊代码块按照与main::中相同的方式和顺序进行处理和运行(或计划运行),因为use本身是BEGIN块。


关于这方面的优秀文档可以在perlmod中找到。来自本节

BEGIN代码块会尽快执行,也就是说,在它被完全定义的那一刻,甚至在解析包含文件(或字符串)的其余部分之前。

由于use语句BEGIN块,因此它们会在遇到时立即运行。从使用

它完全等同于

BEGIN { require Module; Module->import( LIST ); }

因此,包中的BEGIN块在遇到其他块时会与它们一起运行。包中的END块以及其他特殊块也按照相同的顺序进行编译。关于(最终)执行的顺序

END代码块执行得尽可能晚。。。

一个文件中可能有多个END块——它们将按定义的相反顺序执行;即:后进先出(LIFO)

INITCHECK块的编译和执行顺序如下。


这里有一些代码来演示包中使用的这些特殊代码块。

文件PackageBlocks.pm

package PackageBlocks;
use warnings;
BEGIN { print "BEGIN block in the packagen" }
INIT  { print "INIT  block in the packagen" }
END   { print "END   block in the packagen" }
1;

主脚本

use warnings;
BEGIN { print "BEGIN in main script.n" }
print "Running in the main.n";
INIT { print "INIT in main script.n" }
use PackageBlocks;
END   { print "END in main script.n" }
BEGIN { print "BEGIN in main script, after package is loaded.n" }
print "After use PackageBlocks.n";

输出

BEGIN在主脚本中。包中的BEGIN块在加载包之后,在主脚本中开始。主脚本中的INIT。包中的INIT块主要是跑步。使用PackageBlocks之后。在主脚本中结束。包中的END块

main::INIT之前的块相比,包中的BEGIN块按出现顺序运行。CCD_ 16块在末尾运行,并且包中的那个在main::中的那个之后运行,因为在本例中use在它之前。

这很容易为自己测试

use Module(以及require EXPRdo EXPReval EXPR)编译Perl代码,然后立即运行

这就是大多数模块末端的1;被拾取的地方。如果在编译后执行模块的代码,它没有返回true值,则require将使失败

诚然,INITEND块通常没有太多用处,因为运行时阶段与编译密切相关,而且模块通常是关于定义子例程的,但如果您想要,则可以选择

最新更新