> so let's see some proposals for a throw/catch typeof thing or a more
> universal way to propogate errors.

Here's one stab at try/catch
http://search.cpan.org/doc/GBARR/Error-0.13/Error.pm

It's syntax is familiar to C++, Java, and Delphi
programmers. However, there are issues with moving
something like this into the core language. It
introduces several new keywords: try, catch, with,
except, otherwise, finally, and record.

Using RFC22 and RFC23 we could rewrite the above example:

  unlink($file) or die Error::Simple("$file: $!",$!);

  eval {
    do_some_stuff();
    die "error!" if $condition;
    die Error::Simple -text => "Oops!" if $other_condition;
  }
  catch {
    switch( $@ ) {
      case __->isa('Error::IO') {
        print STDERR "File ", $@->{'-file'}, " had a problem\n";
      }
      case __->isa('UserException1') {
        send_message $@->description
      }
      case __->isa('UserException2') {
        send_message $@->description
      }
      print STDERR "Well I don't know what to say\n";
    }
  }
  finally {
        close_the_garage_door_already(); # Should be reliable
  }; # Don't forget the trailing ; or you might be surprised

New keywords are catch and finally. die is changed somewhat.
Catch and finally blocks become part of eval.

Changes to die:

Calling die with a list of strings creates an exception
object. The object overloads the stringify and numify
operators. The overloads call description() and value(),
respectively. The description is whatever was passed to die.
The value defaults to 0. (You have to call die in another way
to set the exception object's value.) Finally, the exception
object includes a stack trace.

Passing an object reference to die causes that object to be 
thrown as an exception. Perl 5 already does this.

Passing an unquoted package name and optional additional
arguments causes that package's constructor to be called
with the extra arguments. The returned object reference is 
then thrown as an exception. This overload of die implies a
standard name for the constructor.

Some comments on finally:

This block is the place to perform clean-up chores. Whatever
resources must be freed when the block exits are freed here.

With the current reference counting scheme, finally is not 
very important. However, if v6 moves to garbage collection, we
need some sort of finally functionality. Garbage collectors
do not guarantee timely destructor calls (where resources are
normally freed). With GC, the need for explicit clean-up of  
rare resources exists -- even in the absence of exceptions.

What is catch?

As shown above, catch is syntactic sugar for

  if( $@ ) { ... }


Making die always throw an object is the largest change. It 
eliminates parsing $@ to log errors in a database. More 
information could be provided for each error. For example,
suppose you use Fatal to call open. On errors it could die
with its own exception class that lists the filename and other
context information. Extra information a la $^E go in the object
too.

> i, of course wouldn't mind seeing some form of callbacks. i 
> am in favor
> of dropping %SIG altogether. my signals rfc (should be done 
> tonight) can
> be modified/copied to support error callbacks of various 
> types including
> the warning and die ones we have now.

Evan Howarth

Reply via email to