MonkeeSage wrote:
> On Dec 3, 8:22 pm, Charles Oliver Nutter <charles.nut... / sun.com>
>> 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