2016-06-09 80 views
0

因为我理解Perl代码中的这些特殊功能,BEGIN和CHECK块在编译阶段运行,而INIT和END块在实际执行阶段运行。Perl中的BEGIN,CHECK,INIT和END块

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

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

+0

这在[编程Perl](http://shop.oreilly.com/product/9780596004927.do)的第16章“编译”中有详细描述 –

回答

4

 在通过use装包的特殊代码块被处理和运行(或计划运行)按照与相同的方式和顺序进行10,因为use本身是一个BEGIN块。


关于此问题的出色文档可以发现in perlmod。从此部分

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

由于use陈述是他们只要遇到运行BEGIN块。从use

这是完全等同于

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

所以BEGIN块在网上与他人包运行,在遇到他们。然后,包中的END块也将按照相同的顺序以及其他特殊块进行编译。至于(最终)执行的顺序,一个END代码块被执行尽可能晚...

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

INITCHECK块编译和执行的顺序遵循西装。


下面是一些代码来演示在一个封装中使用这些特殊的代码块。

文件PackageBlocks.pm

package PackageBlocks; 
use warnings; 

BEGIN { print "BEGIN block in the package\n" } 
INIT { print "INIT block in the package\n" } 
END { print "END block in the package\n" } 
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 in main script. 
BEGIN block in the package 
BEGIN in main script, after package is loaded. 
INIT in main script. 
INIT block in the package 
Running in the main. 
After use PackageBlocks. 
END in main script. 
END block in the package 

包中的BEGIN块中出现的顺序运行时,在比较在main::,以及INIT之前。 END块在结尾处运行, 并且包中的一个在main::之后运行,因为在此示例中use位于它之前。

+0

这并没有解决OP的问题,它是关于Perl模块中的'INIT'和'END'块 – Borodin

+0

@Borodin哦......最后一段绊倒了我,谢谢。我会补充一点。 – zdim

1

这是很容易测试自己

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

也就是说在1;在大多数模块的到底是已接。如果编译之后执行模块的代码不返回值,那么require将失败

诚然,通常也没有一个INITEND块多大用处,因为运行时间阶段是如此密切绑编译,因为模块通常是如何定义的子程序,但选择是那里,如果你想让它