• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

这是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

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
perl调用shell脚本发布时间:2022-07-22
下一篇:
Perl与JS的比较(数组、哈希)发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap