Today I was thinking about retry support in JRuby, and figured we've 
reached a decision point.

retry is a tricky little bugger. It works the way it does in MRI largely 
because of the way the interpreter works; so in that sense it's very 
implementation specific. So here's some example code, see if you can 
figure out what it prints.

$count = 0
class Foo
   def initialize
     $count += 1
     @value = $count
   end

   def do_retry(i)
     puts "value is #{@value} and i is #{i}"
     retry
   end
end

a = 0
Foo.new.do_retry(a += 1) {}

Give up? Here's the answer:

value is 1 and i is 1
value is 2 and i is 2
value is 3 and i is 3

The trick here is the retry. A retry can only be used in a rescue block 
(which is ok), inside a block, or inside a method that's been passed a 
block. Excluding rescue, retry causes the original call to the method 
with the block to reevaluate. And I don't just mean re-execute with the 
same values, I mean re-evaluate both the receiver and the arguments and 
make the call again.

So for example, this method invocation

def foo(a); puts 3; retry; end

(print 1; self).foo((print 2; nil)) {}

Prints out "123" forever, because the receiver (the (print 1; self) bit) 
and the arguments (the (print 2; nil) bit) get executed again. Goofy, right?

This also affects retry within a block

def foo(a); puts 3; yield; end

(print 1; self).foo((print 2; nil)) { retry }

This also prints "123" repeatedly.

The problem I've run into is that it's really cumbersome to implement 
this correctly in the compiler, cumbersome enough I'm debating whether 
we'll support it. There's a few reasons for this:

- retry is handled using exception; so every method call that takes a 
block would have to be wrapped with exception-handling for retry to 
work. Exception-handling is expensive, even if no exceptions are 
actually raised. It would also add a significant amount of code.
- there's no way to know that a method will be reevaluated by looking at 
it, which makes it both dangerous and impossible to predict.
- nobody understands retry, and nobody uses it.

As I understand it, retry in a method body is going away in 1.9, so it 
should be considered deprecated behavior. So far, retry in a block is 
not yet going away, though I'd prefer it did. Actually, I wish this 
behavior never existed, because it makes a lot of assumptions about the 
way Ruby is implemented. Ask if you want to know more about that.

I'm looking for input on this. If there's a way to implement it I have 
missed, please tell me. If you have a concern with this feature being 
disabled, please tell me (it won't affect retry within rescue blocks). 
If you want to talk about it more, please tell me.

- Charlie