Hi! Please consider following me on twitter: @hanekomu.
2009年02月13日
Error::Return
I've released Error-Return. It exports one function,
RETURN, to be used within a try-block (see Error). It is a more intuitive way of returning from the
subroutine that contains the try-block.
try() takes a coderef using the & prototype so
it looks more like a normal Perl block or like map() or
grep(). But the "block" is still just an anonymous subroutine, so
using return within the sub won't do what you think it will do.
For example:
use Error ':try'; sub doit { print " in doit, before try\n"; try { print " in try: start\n"; return 456; print " in try: end\n"; } catch Error with { my $E = shift; print " caught error [$E]\n"; }; print " in doit, after try\n"; } print "before doit\n"; my $x = doit(); print "doit() returned [$x]\n"; print "after doit\n";
The return in the try-block (we call it a block,
but it really isn't) looks like it should return from doit(), but
it doesn't - it just returns from the anonymous sub that was passed to
try(). Therefore, this program prints the following:
before doit in doit, before try in try: start in doit, after try doit() returned [1] after doit
So in doit, after try is still reached, and doit()
returns 1 because of its last print statement.
While that is the correct behaviour, it is unintuitive. This module provides a more powerful way of returning.
Error::Return exports one function, RETURN, which is like
return except that it doesn't just return to its upper scope but
smashes right through it to the next-higher scope. Actually, it skips two
scopes, because it has to return from the try() subroutine as
well. It does take care of the cleanup that try() would normally
perform.
So now you can say:
use Error ':try'; use Error::Return; sub doit { print " in doit, before try\n"; try { print " in try: start\n"; RETURN 456; print " in try: end\n"; } catch Error with { my $E = shift; print " caught error [$E]\n"; }; print " in doit, after try\n"; } print "before doit\n"; my $x = doit(); print "doit() returned [$x]\n"; print "after doit\n";
and it prints
before doit in doit, before try in try: start doit() returned [456] after doit
which is more intuitive.
posted at: 16:46 | path: /dev | permalink | 0 comments | 0 trackbacks
Comments are closed for this story.
Trackbacks are closed for this story.