Perl的特殊代码块:BEGIN、CHECK、INIT、END和UNITCHECK

这是5个特殊的代码块。要理解这几个块,关键在于几个时间点:ui

  • (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是在执行期间执行,因此上面的代码结果为:code

This is the first BEGIN block
This is the second BEGIN block
The program is running

下面程序出现语法错误,但BEGIN也会执行:it

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 =;

执行结果:io

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语句:ast

use File::Find ();
# 等价于
BEGIN {
    require File::Find;
}

END块

END块是在程序执行结束,但退出前执行的,也就是上面的步骤(3)所在期间。require

  • 当触发了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 块生效于程序编译结束以后、执行以前。因此若是语法错误,它们不会被触发。perl

  • 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
相关文章
相关标签/搜索