在BEGIN中重新定义CORE :: GLOBAL :: die

问题描述

我有以下代码

print "Starting..\n";
eval { die "Before die sub redeFinition\n" };
#die "Before die sub redeFinition\n";
BEGIN {
    print "inside Begin block\n";
    *CORE::GLOBAL::die = sub {
        my ($message) = @_;
        print "Message: " . $message ."\n";
    }
}
eval { die "Right after begin block\n" };
print "done\n";

输出如下,

inside Begin block
Starting..
Message: Right after begin block

done

BEGIN块在任何其他语句之前首先执行;但是,CORE::Global::die的重新定义仅在重新定义之后才有效。首先die不使用重新定义的版本,而是原始版本。有人可以帮我在这里找出原因吗?

解决方法

BEGIN使代码块在编译后立即执行,而不是等待编译阶段完成。这意味着BEGIN块中的代码在其他代码执行之前执行,但不一定在其他代码编译之前执行。代码仍然基本上按照看到的顺序进行编译。

要使CORE::GLOBAL覆盖对给定的调用有效,则必须在编译该调用时已安装它。如果没有覆盖,则编译器将发出对内置核心函数的调用。

BEGIN块运行之前,将编译BEGIN块之前文件中的所有代码,因此不会覆盖第一个die调用。

,

hobbs already explained the compile time sequencing,但是,如果要重新定义die,还有另一点要考虑。您不一定需要接触CORE::(尽管处理您无法接触的旧代码是另一个问题)。您可以在die哈希中安装warn(或%SIG)处理程序:

local $SIG{__DIE__} = sub { ... };