in reply to Capturing Text from a die command

You can register a die handler in $SIG{__DIE__}. This example code probably won't work when you have multiple instances of Logger, and it will clobber any die handler the user has set up. But it's a good start:
package Logger; sub new { my $self = ... ... $SIG{__DIE__} = sub { my $msg = shift; $self->add($msg); die $msg; }; return $self; }
A more robust solution is to maintain a list of active Logger instances within the package, and set up just one die handler that writes to all of them.
package Logger; our @instances; sub new { my $self = ...; ... push @instances, $self; return $self; } $SIG{__DIE__} = sub { my $msg = shift; $_->add($msg) for @instances; }
You may also want to take care to not clobber existing die handlers, but I don't know a whole lot about that. I'll leave it to the pros ;)

blokhead

Replies are listed 'Best First'.
Re: Re: Capturing Text from a die command
by or10n (Initiate) on May 14, 2004 at 18:24 UTC
    Works like a charm, I appreciate it. You also just gave me a new subject to read up on. Thanks!
Re: Re: Capturing Text from a die command
by hv (Prior) on May 16, 2004 at 13:13 UTC

    Note that die is often caught in eval, and you usually don't want to log such fake deaths. You can avoid that by checking $^S:

    $SIG{__DIE__} = sub { die @_ if $^S; ... };

    Note that the fake SIG handlers __DIE__ and __WARN__ have special handling: the handler is suspended while running it, so calling die() within the die handler does the right thing.

    This still won't necessarily do the right thing for the commonish idiom of 'load module if available':

    BEGIN { $module_loaded = eval { require Some::Module }; }
    since in that context $^S is set to undef; I'm not aware of any easy way to determine in that case whether or not the failed require is happening inside an eval.

    Hugo