From: Adam Shelly Date: 2008-08-29T09:17:37+09:00 Subject: Re: Writing a method to handle a code block? On 8/28/08, Brian Ross wrote: > On Thu, Aug 28, 2008 at 1:36 PM, Adam Shelly wrote: > > > > The block with 'puts' is stored as code_block, and run 5 times, once > > for each letter in the array: > > %w{a e i o u}.each { |vowel| code_block.call(vowel) } > > > > So the end result is that each vowel is printed out. > > > > Intuitively I'd think that: > > each_vowel {|vowel| puts vowel} > > would lead to something that looked like: > > %w{a e i o u}.each { |vowel| |vowel| puts vowel.call(vowel) } > > which is incomprehensible to me. I guess I am trying to really figure out > how it's working so that I can construct my own and really understand it. To > sound like an idiot: I still don't really understand how it's working. > I'm probably not the best explainer... but you are on the right track. Michael is right that having two things called vowel here can be confusing. So let's rename the variables - the code will work exactly the same: def each_vowel &code_block %w{a e i o u}.each {|item| code_block.call(item) } end each_vowel {|v| puts v} code_block.call(item) simply executes the block using 'item' in place of the variable inside the || pipes, so conceptually, this 'expands' to the following pseudo-code: %w{a e i o u}.each { |item| {|v=item| puts v}} > Alternatively, if I just run > puts each_vowel {} > it returns 5 vowels, each on its own line and seems to function the same as: > each_vowel {|vowel| puts vowel} Something completely different is happening with `puts each_vowel{}`. Remember that Ruby methods return the result of the last line, which for each_vowel, is the result of Array.each, which is the array itself. So after executing an empty block, which does nothing, you are returning the array and passing that to puts. To see the difference, compare to : each_vowel{|v| p v.succ} -Adam