http://www.perlmonks.org?node_id=1072556


in reply to Re^2: Execute function before exit of do() block
in thread Execute function before exit of do() block

Not all helper scripts need (or even can) act on the detected bad event. That is why the detection of the bad event needs to happen inside the helper script, rather than the main script.

What would detection of the bad event (...) inside the helper script script give you, if that helper script cannot act on the detected bad event as you are saying? Error detection has to happen in the main script, checking the for $@ as you already do.

perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Replies are listed 'Best First'.
Re^4: Execute function before exit of do() block
by gri6507 (Deacon) on Jan 29, 2014 at 18:11 UTC
    Allow me to clarify. Let's say that my helper scripts fall into three categories:
    1. ones that have no need to clean up after themselves and thus have no need to detect bad events
    2. ones that need to perform CleanUpX() routine on completion, regardless of how that completion is initiated (i.e. normal exit or a croak)
    3. ones that need to perform CleanUpY() routine on completion, regardless of how that completion is initiated (i.e. normal exit or a croak)
    As you can see, doing a single activity on the main script side is not an option. Each script has to clean up on their own, if needed. The question is how can I force the specific clean up in case of an abnormal exit (i.e. croak) of each helper script?
      The question is how can I force the specific clean up in case of an abnormal exit (i.e. croak) of each helper script?

      As always, TIMTOWTDI. Here's one approach (helper script):

      use warnings; use strict; use Carp; my $cleanup = sub { print "helper cleans up after itself!\n"; }; local $SIG{__DIE__} = $cleanup; print "Hello\n"; croak "bad thing"; print "There\n"; 1;

      Running that with your main script of the OP gives:

      qwurx [shmem] ~ > perl main.pl helper.pl Hello helper cleans up after itself! helper.pl: bad thing at helper.pl line 11 require helper.pl called at main.pl line 6 Done with main

      See %SIG. The local __DIE__ handler is made into an anonymous subroutine assigned to a lexical variable in order to not pollute any namespace.

      update:

      Reading the documentation I linked to, I find the following:

      Due to an implementation glitch, the $SIG{__DIE__} hook is called even inside an eval(). Do not use this to rewrite a pending exception in $@ , or as a bizarre substitute for overriding CORE::GLOBAL::die() . This strange action at a distance may be fixed in a future release so that $SIG{__DIE__} is only called if your program is about to exit, as was the original intent. Any other use is deprecated.

      So... that might be not that sound an advice as I thought it would be. I disagree with this being an implementation glitch, though. A do file should die in the same way as a use, which is also eval at its core. But it is not clear whether the glitchiness applies to all sorts of eval.

      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'