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

Suppose you set up the following:

use Data::Dumper qw(Dumper); $SIG{__WARN__} = sub { &handle_it(@_); warn @_ }; $SIG{__DIE__} = sub { &handle_it(@_); die @_ }; sub handle_it { print Dumper \@_; }


Everything looks great. Should be able to spit out arguments that were passed. Except the following happens:

die "foo"; # prints as "foo at script line whatever\n" - stringifie +d #die "foo", "foo"; # stringified - same as above but with "foofoo" #die {hi => 'there'}; # not stringified - shows correctly as a hashre +f #die 'foo',{hi => 'there'}; # stringified "fooHASH{whatever}" #warn {hi => 'there'}; # always stringified


So, rather than being able to have useful handlers, we are left with a mess. Granted the one case that didn't stringify is great for Object Exceptions like die My::Exception->whatever('foo'), the reason for stringifying in the other cases is mind boggling. It seems that perl should leave the arguments alone until somebody calls die from inside a $SIG{__DIE__} handler or warn from inside the $SIG{__WARN__} handler. I'm sure its all an "internals" issue but still it seems like a poor choice to almost, but not quite, provide the data that was passed along.

So my question. Is there a way turn off stringification entirely for this case. I know that I could send an object as a parameter with a better overloaded stringification mechanism - but that is overkill. I'd love to be able to do:

die "Something happend", {extra_argument_to_show_pretty_error => 1};


I haved looked but my guess is I get to wait for Perl 6 Exceptions.

Thanks for any help.

my @a=qw(random brilliant braindead); print $a[rand(@a)];

Replies are listed 'Best First'.
Re: Argument stringification in __WARN__ and __DIE__
by broquaint (Abbot) on May 14, 2003 at 21:24 UTC
    Except the following happens
    Indeed, I've lamented this in Any last words?. The problem is due to the fact that the __DIE__ signal handler (and all signal handlers for that matter) only expect one argument, so if you ever pass more than one arg to die perl automagically concatenates the arguments. There is one way around it, but it is rather hackish - set $@ to an object and that will be passed to your $SIG{__DIE__} handler (consult the die docs for more info on this behaviour) e.g
    use overload q[""] => sub { "@{$_[0]}" }, fallback => 0; $SIG{__DIE__} = sub { print "dang - ", @{$_[0]}, $/ }; $@ = bless [qw/that didn't work/]; die; __output__ dang - thatdidn'twork that didn't work
    Terrifically hackish, but it works ;)
    HTH

    _________
    broquaint

      Thanks for the reply.
      That could almost be workable. Also I could also do:
      die ["Some error happened", {other => 'args'}];


      Downsides are that it looks ugly if you don't have an __DIE__ handler - and it still doesn't work for __WARN__.

      my @a=qw(random brilliant braindead); print $a[rand(@a)];
        Downsides are that it looks ugly if you don't have an __DIE__ handler
        If you overload the stringification operator for your object then you should be able to get the desired behaviour for die.

        Another option is that you could overload die and warn e.g

        BEGIN { *CORE::GLOBAL::die = sub { CORE::die("$_[0]->{type}: $_[0]->{msg}\n"); }; *CORE::GLOBAL::warn = sub { CORE::warn("$_[0]->{type}: $_[0]->{msg}\n"); }; } warn { type => "warntest", msg => "missing point" }; die { type => "dietest", msg => "and I'm done" }; __output__ warntest: missing point dietest: and I'm done
        Extraordinarily hackish, but at least there's an option :)
        HTH

        _________
        broquaint

Re: Argument stringification in __WARN__ and __DIE__ (p5p)
by tye (Sage) on May 14, 2003 at 20:23 UTC

    die used to stringify even its first argument (like warn still does). I'd search the p5p archives to find discussions from when this change was proposed to get more insight into why only the first argument was "fixed" and only for die.

                    - tye