ForgotPasswordAgain has asked for the wisdom of the Perl Monks concerning the following question:

%SIG says "When a __DIE__ hook routine returns, the exception processing continues as it would have in the absence of the hook, unless the hook routine itself exits via a goto &sub, a loop exit, or a die()". Presumably "continues as it would have in the absence of the hook" means it dies, but what does "the hook routine itself exits via ... a loop exit" mean? Attempts:
$ perl -Mstrict -wE'$SIG{__DIE__}=sub{last}; die "hi"' Exiting subroutine via last at -e line 1. Can't "last" outside a loop block at -e line 1. # no strict $ perl -wE'$SIG{__DIE__}=sub{last}; die "hi"' Exiting subroutine via last at -e line 1. Can't "last" outside a loop block at -e line 1. # no warnings $ perl -E'$SIG{__DIE__}=sub{last}; die "hi"' Can't "last" outside a loop block at -e line 1. # -e instead of -E $ perl -e'$SIG{__DIE__}=sub{last}; die "hi"' Can't "last" outside a loop block at -e line 1. # put last in a while loop, dies $ perl -e'$SIG{__DIE__}=sub{while(1){last}}; die "hi"' hi at -e line 1. # put last in a non-loop block, dies $ perl -e'$SIG{__DIE__}=sub{{last}}; die "hi"' hi at -e line 1.
Edit:
$ perl --version This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-ms +ys-thread-multi

Replies are listed 'Best First'.
Re: exit from $SIG{__DIE__} via a loop exit?
by choroba (Cardinal) on Mar 07, 2025 at 10:15 UTC
    The documentation was fixed 3 weeks ago.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      Thanks, awesome coincidence, heh
Re: exit from $SIG{__DIE__} via a loop exit?
by Corion (Patriarch) on Mar 07, 2025 at 06:48 UTC

    I thought you need a loop surrounding the die, but even that one complains instead of leaving the surrounding loop:

    #!perl use 5.020; $SIG{__DIE__}= sub { next }; for (1..2) { say $_; die; } say "done"; __END__ Can't "next" outside a loop block at tmp.pl line 3.

    I remember that goto/next/last were mildly revamped to eliminate jumping into deeper blocks, and maybe this part of the documentation was not updated there...

Re: exit from $SIG{__DIE__} via a loop exit?
by ikegami (Patriarch) on Mar 07, 2025 at 15:48 UTC

    This is a loop exit:

    sub f { last; } say "before loop"; { say "start of loop"; f(); say "end of loop"; } say "after loop";

    ({ ... } is technically a loop. You can also use while/until loop, a foreach loop, or a C-style for loop.)

    This outputs

    before loop start of loop Exiting subroutine via last at -e line 1. after loop
    So the documentation you quoted refers to programs such as the following:
    $SIG{ __DIE__ } = sub { last; }; say "before loop"; { say "start of loop"; die "!"; say "end of loop"; } say "after loop";

    However, the code doesn't do what the documentation claims it does.

    before loop start of loop Can't "last" outside a loop block at -e line 1.

    choroba pointed out that the documentation was corrected a short while ago.

    However, the documentation is wrong, and it was corrected a short while ago. (Thanks to choroba for identifying this.)

      Thanks, so at least I did understand what "exits via a loop exit" meant, but was led astray by the doc mismatch