From: Charles Oliver Nutter Date: 2007-12-04T13:40:18+09:00 Subject: Re: Everyone's favorite flow control: retry MonkeeSage wrote: > On Dec 3, 8:22 pm, Charles Oliver Nutter >> Retry outside a rescue actually allows you to jump back across call >> boundaries and start an invocation again. Scary. >> >> - Charlie > > Ah. How does it unwind the stack like that? Is that what you meant > about implementation specific stuff? It raises an exception, a LocalJumpError (which is how all non-local flow control works) which is then handled further up the stack. The reason it's implementation-specific is because the behavior ends up being a side effect of MRI's interpreter. The following call: foo {} Parses into an AST like this: Iter # this represents the block FCall :foo # this represents the call receiving the block nil # no args to the call Outside of a rescue, retry bubbles out to the nearest Iter. If there is none, it bubbles all the way out and terminates execution. The implementation-specific bit here is the fact that Iter contains FCall, rather than the more intuitive reverse; this causes the retry to go all the way back above the FCall and try it completely anew, reevaluating its receiver and arguments in the process. In compiled implementations or implementations with a different AST, this doesn't map well. It's very specific to the way MRI represents Iter/Call in the AST. > Ps. I don't think anyone will miss retry outside of a rescue. I won't > at least. :) I've just disabled it outside of rescue in JRuby trunk; we'll see how that goes. So far, nothing seems breaks. - Charlie