[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