Perl的特殊代碼塊:BEGIN、CHECK、INIT、END和UNITCHECK
阿新 • • 發佈:2018-10-13
變量 con 代碼 方式 cond second begin require pri
這是5個特殊的代碼塊。要理解這幾個塊,關鍵在於幾個時間點:
- (1).程序編譯期間
- (2).程序執行期間
- (3).程序執行結束但還未退出期間
BEGIN塊
- BEGIN塊是在程序編譯期間執行的,也就是上面的步驟(1)所在期間
- 即使程序中出現了語法錯誤,BEGIN塊也會執行
- 如果出現了多個BEGIN塊,則按照FIFO(first in first out)的方式輸出,也就是從上到下的順序
在BEGIN期間可以做一些程序執行之前的操作,例如事先給某個比較特殊的變量賦值,檢查文件是否存在,檢查操作系統是否滿足要求等等。
package Foo; use strict; use warnings; BEGIN { print "This is the first BEGIN block\n"; } print "The program is running\n"; BEGIN { print "This is the second BEGIN block\n"; }
由於BEGIN代碼塊在編譯期間執行,程序普通行的print是在執行期間執行,所以上面的代碼結果為:
This is the first BEGIN block
This is the second BEGIN block
The program is running
下面程序出現語法錯誤,但BEGIN也會執行:
BEGIN { print "This is the first BEGIN block\n"; } print "The program is running\n"; BEGIN { print "This is the second BEGIN block\n"; } my $x =;
執行結果:
syntax error at some_program.pl line 8, near "=;"
Execution of some_program.pl aborted due to compilation errors.
This is the first BEGIN block
This is the second BEGIN block
不過上面的error信息不一定會最先輸出,因為stdout和stderr是兩個獨立的文件句柄,無法保證它們之間的順序。
實際上,use導入模塊時如果導入的是空列表,它等價於在BEGIN中使用require語句:
use File::Find (); # 等價於 BEGIN { require File::Find; }
END塊
END塊是在程序執行結束,但退出前執行的,也就是上面的步驟(3)所在期間。
- 當觸發了die的時候,它們也會執行
- 但可以通過信號來忽略END
- 它們的執行順序是LIFO(last in first out),即從下往上輸出
- END常用來做清理、善後操作
END {
print "This is the first END block\n";
}
END {
print "This is the second END block\n";
}
輸出結果:註意,先輸出second END,再輸出first END
This is the second END block
This is the first END block
INIT、CHECK 和 UNITCHECK 塊
INIT、CHECK 和 UNITCHECK 塊生效於程序編譯結束之後、執行之前。所以如果語法錯誤,它們不會被觸發。
- CHECK在編譯結束後立即執行,即上面步驟(1)剛完成之後,輸出格式為LIFO
- INIT緊跟在CHECK之後,也是在步驟(2)之前,輸出格式為FIFO
- UNITCHECK是在perl 5.9.5之後引入的功能。用於解決執行期間require或do或eval導入文件時不觸發CHECK和INIT的問題(因為這些語句的導入是在執行期間進行的,而這兩個塊是在編譯期間進行的)。UNITCHECK是在導入的文件剛編譯完成之後、執行之前立即執行的
INIT {
print "This is the first INIT block\n";
}
CHECK {
print "This is the first CHECK block\n";
}
INIT {
print "This is the second INIT block\n";
}
CHECK {
print "This is the second CHECK block\n";
}
輸出結果:
This is the second CHECK block
This is the first CHECK block
This is the first INIT block
This is the second INIT block
Perl的特殊代碼塊:BEGIN、CHECK、INIT、END和UNITCHECK