Writing a method to handle a code block?

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 }

I am trying to figure out how that works but I’m still having a bit of
trouble. Could someone break it down bit by bit to show what it’s doing?

def each_vowel(&code_block)

It defines a method that takes a code block (is the & necessary?). What
does
it mean to have a method that takes a code block?

%w{a e i o u}.each { |vowel| code_block.call(vowel) }

Then it takes an array of vowels, which call the each method to pass
each
one into the following block through |vowel| as a block argument. The
block
arguments are then called by the variable code_block (I don’t understand
this).

Brian

On 8/28/08, Brian R. [email protected] wrote:

def each_vowel(&code_block)

It defines a method that takes a code block (is the & necessary?).

Yes the & is necessary, otherwise when you try to call this method
with each_vowel {|v|puts v} you will get an argument error, since
the method will expect a normal object, not a block.

What does it mean to have a method that takes a code block?

At first approximation you can think of a code block as an anonymous
method.
You are writing a method that can take another method as an argument.

%w{a e i o u}.each { |vowel| code_block.call(vowel) }

Then it takes an array of vowels, which call the each method to pass each
one into the following block through |vowel| as a block argument. The block
arguments are then called by the variable code_block (I don’t understand
this).

code_block.call(vowel) is calling the method stored in the code_block
variable, and
passing it the argument called vowel. When you call each_vowel like
this:

each_vowel {|vowel| puts vowel}

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.

HTH,
-Adam

On Thu, Aug 28, 2008 at 1:36 PM, Adam S. [email protected]
wrote:

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.

Brian

Brian R. wrote:

def each_vowel(&code_block)

Brian

Code (in the form of Proc objects and similar) can be stored in a
variable.

code = proc { puts “test” }
=> #Proc:0xb7b03030@:25(irb)

code.call
test
=> nil

The &argument to each_vowel is a local variable that stores any block or
closure passed to it using the special method() { syntax }. After that,
calling argument.call is the same as code.call in the previous example.

I got a little turned around in your question, either I’m just not
understanding it or you’re using a term wrong. The each method itself
takes a block, the block is everything in the { curly braces }. The
argument to the block is |vowel|, for every vowel in the array, the code
block passed to each is called with that vowel passing it in |vowel|.
That code block then goes an calls the code_block argument, which in
turn contains the code block given when you called each_vowel.

I can see how that explanation gets a little confusing. Two things are
called vowel, there are three things called a “code block,” and a few
layers of calls through the code blocks. This example may be simpler.
It duplicated the Fixnum#times method.

def this_many_times(n,&block)
n.times { block.call }
end
=> nil

this_many_times(10) { puts “test” }
test
test
test
test
test
test
test
test
test
test
=> 10

On 8/28/08, Brian R. [email protected] wrote:

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

On Thu, Aug 28, 2008 at 3:27 PM, Brian R. [email protected]
wrote:

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.

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}

Maybe my question is, what is the importance of the second |vowel|? Does
the
first block argument just get passed to the second block through
whichever
block argument is given in the second? Also I’m having trouble with the
documentation for the call method to figure out how it works.

Brian

On Thursday 28 August 2008 12:12:07 Brian R. 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

Thank you, everyone. If I understand correctly:

&foo just means that whatever is passed to it (& requires a code block)
will
be saved as a local variable that may be used later.

The call method executes the block that it acts on and then executes it
but
first assigns the block’s | block argument | to the parameter passed to
it.

Is it then that yield functions the same as the call method? I haven’t
quite
gotten to proc objects yet, but it looks like using & converts the code
block into an object, but yield, strictly, doesn’t? Are code blocks the
exception to the “everything in ruby is an object” rule?

I’m certainly understanding this far better than I was previously, I
think.

Brian

As far as I understand it, passing a parameter to a method prefixed with
&,
or the return value of ‘lambda’, creates or passes in
a Proc object which can continue to be called after the original
function
call has gone out of scope i.e. a closure.

Yield by contrast is a way of communicating with a code block inside a
method, and the block can talk back. More useful
in iterations, transactions and so on.