I was trying to use blocks in ruby and had code of this form:
1 2 def wangle 3 while true 4 nValue = rand(10) 5 if yield( nValue) 6 return 7 end 8 print "THIS IS NEVER PRINTED" 9 end 10 end 11 12 def wibble 13 wangle do |nValue| 14 return nValue == rand(10) 15 end 16 end 17 18 wibble()
The method 'wibble' calls 'wangle' passing it a block of code to execute. Wangle is supposed to keep calling this block until two random numbers match. if the numbers match it will return true and cause the loop to terminate. However, the loop will always terminate immediately, the string "THIS IS NEVER PRINTED" is never printed.
The reason for this is blindingly obvious in hindsight and after analysing the small print describing the yield command. This says "the value of the last expression evaluated in the block is passed back to the method as the value of the yield". Notice how it doesn't mention the 'return' keyword? This is because the return keyword is being applied to the outer method 'wibble' and that is returning to whatever called it, completely bypassing 'wangle' on it's way up the call tree. If 'wibble' is changed to:
def wibble wangle do |nValue| nValue == rand(10) end end
then it will pass the results of the comparison "nValue == rand(10)" back to wangle to deal with as I originally intended.
I can imagine that this subtlety was permitted as there may be occasions when you want wibble to be able to return directly to it's caller. In my ruby noobyness I'm getting blocks mixed up with methods. Unfortunately I like using the return keyword, it makes code easier to skim read, it waves a big flag to me that says THIS IS THE RETURN VALUE.

