in reply to Re3: How to detect a die() without catching it?
in thread How to detect a die() without catching it?

Mid-air collision of update and reply! Eee gads. Ok, I see what you mean about not needing to die() from &$SIG{__DIE__}. (Although, BTW, this recursion isn't "bad" - it's actually recommended in the die() docs as the way to change the error message!)

But I think my concern about the call stack still stands. How can a single global handler be enough?

UPDATE: To clarify, here's an example of how $SIG{__DIE__} doesn't behave the way I think I would need it to:

sub catcher { local $SIG{__DIE__} = sub { print "Caught 1!\n"; }; catcher2(); } sub catcher2 { local $SIG{__DIE__} = sub { print "Caught 2!\n"; }; sub_that_dies(); } sub sub_that_dies { die "Foo"; } catcher();

Now, I'd like that code to print both "Caught 1!" and "Caught 2!". But what it actually does is less useful:

$ perl bomb.pl Caught 2! Foo at bomb.pl line 30.

Does that make it clear what I mean?

-sam

Replies are listed 'Best First'.
Re: Re: Re3: How to detect a die() without catching it?
by belg4mit (Prior) on May 17, 2002 at 23:37 UTC
    Well I was a bit hasty in calling it recursion, as it isn't really.

    So actually you want the opposite (in a manner of speaking) of what you said, you wish to artificially enforce inheritance of die as *exceptions*. The code you give does exactly what it is supposed to, there is no die called within catcher, and $SIG{__DIE__} is re-localed to the catcher2 scope.

    I think Exception::Class is what you want for that. Alternatively, here's some ugly code

    local @stack; $SIG{__DIE__} = sub { die(@stack, @_); }; catcher(); sub catcher { local @stack = (@stack, "Caught 1!\n"); catcher2(); } sub catcher2 { local @stack = (@stack, "Caught 2!\n"); sub_that_dies(); } sub sub_that_dies { die "Foo"; }

    If, on the other hand, you actually want what's in yor original code, which is just to do something before (outter) dieing then I stand by the original suggestions, and also add END to the list; END output comes last though.

    #=begin a require 'b'; print "Hello World\n"; #This die can also be replaced with print && exit $SIG{__DIE__} = sub { print "BOB!\n"; die(@_); }; a::a(); END{ print "Waka waka\n"; #=end a #=begin b package a; sub a{ die("A!"); } 1; #=end b __END__ Hello World BOB! A! at /tmp/b line 3. Waka waka

    --
    perl -pew "s/\b;([mnst])/'$1/g"

      You're probably correct that what I want are exceptions, but I don't think I can get them. I'm writing a profiler and it's supposed to work with a wide range of code, most of which will be using straight die()s.

      Thanks for the help!
      -sam