CORE::GLOBAL::die redefinition inside BEGIN

172 Views Asked by At

I have the following code

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

Output is as below,

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

done

BEGIN block gets executed first before any other statement; however redefinition of CORE::Global::die is effective only after the redefinition. First die doesn't use the redefined version but the original. Could someone please help me figurr out the cause here?

2

There are 2 best solutions below

0
hobbs On BEST ANSWER

BEGIN makes a block of code execute immediately after it's compiled, instead of waiting for the compile phase to complete. That means that code in BEGIN blocks executes before other code executes, but not necessarily before other code compiles. Code still compiles basically in the order that it's seen.

For a CORE::GLOBAL override to have effect on a given call, it has to have already been installed when that call is compiled. If there is no override, then the compiler will emit a call to the builtin core function.

All of the code in your file before the BEGIN block is compiled before the BEGIN block runs, so the first die call there isn't overridden.

0
brian d foy On

hobbs already explained the compile time sequencing, but there's another point to consider if you want to redefine die. You don't necessarily need to reach into CORE:: (although dealing with legacy code you can't touch is a different issue). You can install a die (or warn) handler in the %SIG hash:

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