10 Apr '13, 7am

@alex_gaynor @evanphx FWIW:

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 ...

Full article: http://www.ruby-forum.com/topic/130702