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

RE: A common base exception object for Perl - RFC



I like your write up. I have a some suggestions.

1. Make the base class minimal. Do not include any special fields like
'name', 'errcode', or 'exitcode'. Don't include any fields or methods, just
the '""' override.

2. 'toString' instead of 'render'.

3. Base implementation of '""' as follows:
	sub { $_[0]->can('toString') ? $_[0]->toString() : "" };
   Just enough to avoid errors with existing code, without requiring a
conversion function to exist.

4. This needs to work:
	my $e = new Exception;
	die $e;
   It should not be necessary to write:
	$e->raise;

5. Will Carp routines behave properly? I know that 'die' will happily pass
along a reference in $@, but won't Carp always stringify it? What would be
the point of using a reference type which was always converted into a string
before it could be caught? Regardless, I think it would be more natural to
write:
	confess $e;
	
Rationale:
  Right now everyone assumes that every $@ is a string. It would be little
improvement (for me, at least) to assume that everything in $@ is either a
string or a HASH ref which has a field 'errcode'.

I would want to see a model which encouraged/forced subclassing of Exception
in order to get a useful exception object, resulting in code like:

	if ( ref $@ and $@->isa{'MyException') ) { ... }

instead of code like:

	if ( ref $@ and $@->{class} eq 'MyException' ) { ... }

The Exception object model should not preclude the use of "better" Perl
objects which are not based on HASH refs (or pseudohashes). If common
practice is to treat $@ as "A string or a HASH ref", it becomes impossible
(again!) to use arbitrary reference types in $@.


-----Original Message-----
From: Pete Jordan [mailto:pjordan1@email.mot.com]
Sent: Thursday, January 20, 2000 5:58 AM
To: Perl5 Porters
Subject: A common base exception object for Perl - RFC


OK, I suppose somebody's gonna do it; might as well be me...

These are my initial ideas, constructive suggestions are most welcome
bearing in mind that this is intentionally a fairly simple base class.

RATIONALE

To provide a common base exception object class for Perl to encourage
interoperability between specific implementations. Usage of this module
should not break any existing standard C<eval> and C<$@> processing.

NAMESPACE

I would like this to be Exception. This does, however, conflict with
Peter Seibel's[1] exception module and intersects with Joshua
Pritikin's[2] Exception::Cxx. This may or may not be a problem.

PROPOSED INTERFACE

	use Exception qw(-stacktrace);

	my $e=new Exception 'text';

	my $f=new Exception -text=>'foo', -class=>'Error',
			-name=>'bar', -errcode=>$!, -exitcode=>23;

	raise Exception 'text';

	raise Exception -text=>'foo', -class=>'Error',
			-name=>'bar', -errcode=>$!, -exitcode=>23;

	my $string=$e->render;	# overloaded from '""'

	my $text=$e->text;
	my $old=$e->text('new');

	my $class=$e->class;
	my $name=$e->name;
	my $exitcode=$e->exitcode;
	my $errcode=$e->errcode;

	Exception->stacktrace($yesno);
	my $stack=$e->stack;

	$e->croak;
	$e->confess;

There are a fair number of methods/fields in there; my guess (which may
be wrong) is that they're the set that most people are most likely to
want.

I'm not planning to put any code in to deal with specific values of
class or name, I just want to provide a standard interface for anyone
who does want to so do.

Exitcode will default as per standard C<die> processing, it's there so
programmers can specify their own if they wish.

Errcode gets its own field so its dual nature can be retained. For
example:

	eval {
	  open FOO, '<bar'
	    or raise Exception "Can't read bar", -errcode=>$!;
	  ...
	};

	print STDERR "$@\n" if $@;

might print:

	Can't read bar: [2] No such file or directory

on failure.

IMPLEMENTATION

As you'd expect; a blessed hash reference, with:

	use overload '""'=>sub {shift->render};

In deference to Larry, I'll not create a C<$SIG{__DIE__}> handler (by
default at least) so:

	eval {
	  die 'whatever';
	};

	$@ and $@->croak;

won't work.

Pete

[1] PSEIBEL   Peter Seibel <seibel@organic.com>
[2] JPRIT     Joshua N. Pritikin <jpritikin@pobox.com>
-- 
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:
Martyn Pearce <m.pearce@inpharmatica.co.uk>
Pete Jordan <pjordan1@email.mot.com>

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