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

Just out of curiousity...is there a reason why MRI has Iter closing on
the FCall rather than the other way 'round? Or is it just incidental?

Regards,
Jordan