2016-06-09 66 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塊多大用處,因爲運行時間階段是如此密切綁編譯,因爲模塊通常是如何定義的子程序,但選擇是那裏,如果你想讓它