'next', 'last' out of subroutine
"Jonathan Swartz" <[email protected]>
| Newsgroups | gmane.comp.web.mason.devel |
|---|---|
| Message-ID | <[email protected]> |
I have been operating for a while under the assumption that an eval {}
around a subroutine will always give you a chance to execute code after the
subroutine is done. However, I've just realized this is not the case: you
can 'next' or 'last' out of subroutine to a loop in the caller. e.g. this
program
sub bar { next; }
sub foo { print "starting foo\n"; eval { bar() }; print "finished
foo\n" }
print "starting loop\n";
for (1) {
foo();
}
print "finished loop\n";
outputs
starting loop
starting foo
finished loop
under perl 5.6.1. I find it odd since the Perl manual for 'next' and 'last'
says
[`next'|'last'] cannot be used to exit a block which returns a
value such
as `eval {}', `sub {}' or `do {}', and should not be used to
exit a grep() or map() operation.
Am I misinterpreting this statement? I do see that some modules actually
depend on this behavior (e.g. Test::More for its skip() subroutine).
Anyway, the way this relates to Mason is that Request::comp has always
relied on regaining control after its eval {} so that it can clean up its
stack. But if you have a loop in one component, and a 'next' or 'last' in
its child component, you can skip Mason's cleanup code entirely and end up
with a corrupted stack.
If this is a Mason "bug", it'll be a real pain to fix - we'll have to
rewrite every bit of code that depends on a reliable exit from eval {}.
Bleah.
Jon
-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g.
Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id=3149&alloc_id=8166&op=click