Witness:

$a = 0

def foo(a)
   $a += 1
   retry if $a < 4
end

(puts 'here'; self).foo((puts 'there'; nil)) {}

Output:

~/NetBeansProjects/jruby $ ruby test.rb
here
there
here
there
here
there
here
there

What's happening here is that a retry within a method body (which works 
*only* if the method has been passed a block) causes both the receiver 
and the arguments to the original call to be re-evaluated.

Sure, it's useful for this:

def my_while(cond)
   return unless cond
   yield
   retry
end

my_while(a < 4) { do something }

But there's a serious danger here. I could define APIs that cause the 
caller's code to do things the caller did not intend:

# two operations that I *must* invoke only once
def open_singleton; end
def something_else; end

create_singleton.foo(something_else) { some body }

If foo is implemented with a retry as above, it will cause 
create_singleton and something_else to get called several times. Even 
worse, there's no way to know by looking at it and no way to avoid it. 
The call to the method has undetectable, unavoidable, potentially 
dangerous side effects on the caller.

I do not believe a target method should be able to cause the caller 
method to behave this way. I believe this behavior should be 
deprecated/removed.

- Charlie