[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]

Re: __DIE__ and exception hooks



Tom Christiansen wrote:

> In logic so simple as this, nobody but *nobody* else had jolly well
> better be folding, spindling, or mutilating that exception, for to
> do so is an abhorrent notion that tosses all dependability and
> determinism out the window and then proceeds to forget just what
> window was so abused.  This bug has broken the code of many careful
> and professional programmers through unforeseeable interactions
> with wicked modules.

So what it comes down to is:

1. Perl provides an (experimental) facility to pass references into
C<die> that will, with a horrible inevitability, find their way into
C<$@> when C<eval> is in use.

2. If anyone makes use of this facility in a module (outside of the sort
of closed system in which I'm currently operating), they will break not
only conventional usage of C<$@> but also Perl's own default C<die>
processing. Though the latter of course can be overridden. Probably
simultaneously in a variety of mutually incompatible ways by different
module authors.

There are three possible solutions:

A. Abandon structured exceptions in Perl. Not an acceptable option.

B. Force the lusers to rewrite all their evals. Muharharharhar... etc.

C. Define a Standard Perl Minimal Exception Object and integrate it such
that, at the very least, scalar fetch access to C<$@> returns an error
text string regardless of whether text or object were passed to C<die>.

It's a pity that a tied scalar can't be used to get at arbitrary methods
in the class it's tied to. Tying C<$@> would mean that its
exception-ness wouldn't be assignable directly, but adding an extra
method that returned an untied object reference wouldn't be a hardship.

A slight variation on what I use here:

  use Exception qw(-stacktrace);

  eval {
    ...
    die 'foo'; # mapped to Exception::raise using $SIG{__DIE__} >;)
    ...
    raise Exception 'bar';
    ...
    raise Exception -class=>'Fatal', -text=>'baz', -exitcode=>23;
    ...
  };

  if ($@) {
    # Can't have both the following two lines working as things stand
    my $text1=$@->text;		# assign error text
    my $text2=$@;		# same as above using tie

    my $error=$@->exception;	# assign error object reference

    # aside from the first line, this is pretty much my
    # Exception::croak method:
    print STDERR "$@\n";
    my $stack=$@->stack;

    if ($stack) {
      print STDERR "Stack trace:\n";

      print STDERR map {
        "\t$_->{PACKAGE}\t$_->{FILE}\t$_->{LINE}\t$_->{SUBNAME}\n"
      } @$stack;
    }

    exit $@->exitcode;
  }

Pete
-- 
use Disclaimer::Standard;	# Motorola GSM Software Factory
my $phone='+44 1793 564450';	# "'Not twisted,' Salzy once said of
my $fax='+44 1793 566918';	#  her own passion, 'it is helical.
my $mobile='+44 7973 725120';	#  That sounds better.'"


Follow-Ups from:
Gurusamy Sarathy <gsar@ActiveState.com>
References to:
Tom Christiansen <tchrist@chthon.perl.com>

[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]