根据我对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)
INIT
和CHECK
块的编译和执行顺序如下。
这里有一些代码来演示包中使用的这些特殊代码块。
文件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 EXPR
、do EXPR
和eval EXPR
)编译Perl代码,然后立即运行
这就是大多数模块末端的1;
被拾取的地方。如果在编译后执行模块的代码,它没有返回true值,则require
将使失败
诚然,INIT
或END
块通常没有太多用处,因为运行时阶段与编译密切相关,而且模块通常是关于定义子例程的,但如果您想要,则可以选择