On Thursday 28 August 2008 12:12:07 Brian Ross wrote: > From Beginning Ruby: > > def each_vowel(&code_block) > %w{a e i o u}.each { |vowel| code_block.call(vowel) } > end > each_vowel { |vowel| puts vowel } First, I'd like to show a simplified version of it. I think this works: def each_vowel %w{a e i o u}.each { |vowel| yield vowel } end In the simplest form, to define a method that takes a code block, you can ignore the block until you need it, and then call it with "yield". This will actually execute faster, but it's not as flexible. You can also call 'block_given?' to find out if you have a block. So... > It defines a method that takes a code block (is the & necessary?). Strictly, no. > What does > it mean to have a method that takes a code block? ALL methods can take a code block. Most of them don't do anything with it. You can verify this: "foo".length {|x| raise "THIS BLOCK SHOULD NEVER BE CALLED!!!" } So, with that in mind, the &foo says that you're binding whatever code block was passed in to a local variable, so you can do things to it. > %w{a e i o u}.each { |vowel| code_block.call(vowel) } %w{a e i o u}, of course, translates to ['a', 'e', 'i', 'o', 'u'] The rest is a simple each loop. You could also do this: ['a', 'e', 'i', 'o', 'u'].each do |vowel| puts 'I got a vowel!' puts vowel end That block runs once for each vowel. To make it simpler, you could disregard all the less common vowels, and just use 'e': def each_important_vowel(&code_block) code_block.call('e') end If you're using it like in your example: each_vowel {|vowel| puts vowel} The easiest thing to do is to think of the code block as a function in its own right. (It's not, which is one of the more disappointing things about Ruby, but we can pretend that it is.) So, it's really more like this: def my_code_block(vowel) puts vowel end %w{a e i o u}.each {|vowel| my_code_block(vowel) } If you made it through that, I'd like to justify my claim that yielding isn't as flexible as the &block syntax. I'd say, yield when you can, and use &block when you need to. One example would be stored callbacks. I'm not sure what you've done with classes and objects, so I'll simplify this: before_printing_callbacks = [] def before_printing &block before_printing_callbacks.push(block) end # Call it a few times, with various arguments... # Then take a look at what's in that array. def print_stuff string before_printing_callbacks.each do |block| block.call end print string end