[Perl5-syntax] Syntax/implementation for try/catch

Ash Berlin ash_cpan at firemirror.com
Tue Jan 13 19:26:49 GMT 2009


So eval sucks. I want proper try catch semantics. Some thing like this:

sub foo {
   my ($self) = @_;
   try {
     $self->some_call_that_dies;
     return (qw/return value from foo/);
   }
   catch (My::Error $e where { $_->code >= 400 } ) {
     print("got My::Error code " . $e->code . "\n");
   }
   catch (Str $e) {
     print("Got str error: $e\n");
   }
   catch ($e) {
     print("Got unknown error: $e\n");
   }
   # $@ will be undef/previous value here.
}


(My prototype/code is at http://github.com/ashb/trycatch/tree/master )

Thanks to Vincent Pit's Scope::Upper I can now make return from a  
block/anon sub return to from the enclosing sub. Wonderful. However  
consider the two cases below:

sub simple_return {
   try {
     return "simple_return";
   }
   return "bar";
}
sub simple_no_return {
   try {
     "simple_return"; # Not a return op
   }
   return "bar";
}

is(simple_return(), "simple_return");
is(simple_no_return(), "bar");

The issue here is detecting an explicit return versus returning value  
of last statement. The way I managed it currently is by a custom  
PL_runops. However rafl pointed out that this would likely mess up  
debugging. He also suggested that it should be possible using  
B::Hooks::{Check,OP::PPAddr}, and for the simple cases above that  
would work. However I *think* it wouldn't work for the cases below.  
Please tell me I'm wrong :)

sub bar {
   # ...
   return "bar";
}

# I'm not sure I can even make devel::declare parse this one properly
# since there is no scope to post hook.
sub foo {
   try \&bar
}

sub foo_2 {
   try {
     goto \&bar
   }
}

All the other problems are basically variations on these two, centered  
around try being called with another block that has already been  
compiled, so B::Hooks::Check can't change the PPAddr for the return op.

Any questions? Any solutions?

-ash



More information about the Perl5-syntax mailing list