Perl的特殊代码块:BEGIN、CHECK、INIT、END和UNITCHECK
这是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
Linux系列文章:https://www.cnblogs.com/f-ck-need-u/p/7048359.html
Shell系列文章:https://www.cnblogs.com/f-ck-need-u/p/7048359.html
网站架构系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.html
MySQL/MariaDB系列文章:https://www.cnblogs.com/f-ck-need-u/p/7586194.html
Perl系列:https://www.cnblogs.com/f-ck-need-u/p/9512185.html
Go系列:https://www.cnblogs.com/f-ck-need-u/p/9832538.html
Python系列:https://www.cnblogs.com/f-ck-need-u/p/9832640.html
Ruby系列:https://www.cnblogs.com/f-ck-need-u/p/10805545.html
操作系统系列:https://www.cnblogs.com/f-ck-need-u/p/10481466.html
精通awk系列:https://www.cnblogs.com/f-ck-need-u/p/12688355.html