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

chocolateboy chocolate at cpan.org
Sun Jan 18 05:15:31 GMT 2009


Hi.

I agree with Florian that the best option is to document the cases that =

don't work rather than trying to add unexpected semantics to code that's =

already been compiled. However, lexically it should be possible to =

promote implicit returns to explicit returns. The rules should be pretty =

straightforward (i.e. pretty much the same rules that Scheme uses to =

identify tail calls <http://tinyurl.com/a8lp62>):

1) The last statement in a sub (unless the last statement is a loop or =

exception (or already a return))
2) If the last statement is a cond_expr, then promote the implicit =

returns in its consequent and alternate branches

2) would need to be applied recursively to handle the fact that:

    if ($foo) {
        foo();
    } elsif ($bar) {
        bar();
    } else {
        baz();
    }

is turned into:

    if ($foo) {
        foo();
    } else {
        if ($bar) {
            bar();
        } else {
           baz();
        }
    }

You could splice in a hook for OP_LEAVESUB (&c.) and then delegate the =

heavy lifting to a perl sub using B::Generate. Or just do it all in C.

It might make a useful pragma =

<http://search.cpan.org/perldoc?Jifty::View::Declare::Compile> (or =

stricture =

<http://search.cpan.org/perldoc?Perl::Critic::Policy::Subroutines::RequireF=
inalReturn>) =

in its own right.

You could also promote all implicit returns to explicit returns globally =

with a peep plug (or by using optimizer.pm (if someone can be persuaded =

to apply the patch that revives it) and B::Generate), but that would =

surely break things (at the very least some of the tests for B:: modules).

chocolateboy

P.S.

Have you considered using Coro::State =

<http://search.cpan.org/perldoc?Coro::State> along with/instead of =

Scope::Upper? That implements setjmp/longjmp-style non-local jumps. =

Maybe that might offer another solution?

Ash Berlin wrote:
> So eval sucks. I want proper try catch semantics. Some thing like this:
>
> sub foo {
>   my ($self) =3D @_;
>   try {
>     $self->some_call_that_dies;
>     return (qw/return value from foo/);
>   }
>   catch (My::Error $e where { $_->code >=3D 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
>
> _______________________________________________
> Perl5-syntax mailing list
> Perl5-syntax at lists.scsys.co.uk
> http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/perl5-syntax
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/perl5-syntax/attachments/20090118/5=
3b03c9c/attachment.htm


More information about the Perl5-syntax mailing list