Subject: | Calling return from within a try block does not leave function |
As discussed on http://www.perlmonks.org/index.pl?node_id=278900 and
elsewhere, wrapping parts of a function in a try/catch block will cause
any return statements found within to become ineffective - the returned
value being stuck as value of the try "operator" rather than passed as
return value of the function.
use Error qw( :try );
sub test {
try {
return "Within try";
} catch Error::Simple with {
};
return "End of function";
}
print test()."\n";
In the above code, I would have liked to se "Within try" returned rather
than "End of function".
This is ofcourse how eval behaves in perl, but is it not how try/catch
behaves in other languages. It is a very error prone behaviour.
A problem with evals is that there appears to be no way to determine if
a "return" call was made or if the value of the eval is simply the
result of the last call to "print", "syswrite" or whatever.
A potential solution (ugly, evil etc) would be to locate the B::OPs (or
rather B::LISTOP) for "return" calls and wrap them with something to let
the calling function ("try") know that an actual return call was made. A
"local" scoped bool should do the trick. I have had some success with
B::Utils::walkoptree_filtered and B::Generate, but my knowledge of the
Perl guts is lacking.