From: Richard Lawrence Date: 2007-07-12T01:10:00+09:00 Subject: Catching what a block returns (A newbie lesson learned) Hello all, This is a message intended to be from one newbie to another. Until last night, I couldn't quite understand something about Ruby blocks: namely, how to get anything back from them. I have read a number of tutorials that try to explain blocks, and they always use trivial examples like this: def verbose_call(x) puts "I am calling a block now!" yield x puts "I am done calling the block!" end and then you can do wonderful things like: verbose_call(3) {|n| puts n + 1} verbose_call("Jenny") {|name| puts name + " from the block."} This is all well and good, but it seemed to me that this couldn't be all there was to the much-acclaimed power of blocks. Then I saw things like: [1, 2, 3].inject(4) {|sum, elt| sum + elt} # => 10 and became confused. Clearly, the value returned by the block is secretly being caught by inject(), then fed back into the block...but how? This seemed a long way from the trivial examples: there, blocks were a dead end, but here, there was two-way communication happening between the method and the block. The solution (of course) was to realize that "yield" actually evaluates to something. Thus, def catch_block_value result = yield puts "I got this from the block: ", result end Realizing that "yield" evaluates to something I can assign to variables, etc. was important for getting beyond the trivial examples. In retrospect, I should have paid more attention to the lesson that *everything* evaluates in Ruby. I think what I was hung up on is that "yield" is a keyword (right? at least it looks like one), and hence I thought of it as mere flow control, not a passage for information. So, again, totally trivial for all you veterans out there, but I hope that this clears some things up for someone like me. Is there any documentation that I can help improve by doing a little write-up of this? Richard