Info on block arguments

I’m trying to pick up ruby and I’m impressed by all the cool stuff it
does out of the box. I’m reading a few books but i’m finding why’s
poignant guide to ruby to be the most helpful and entertaining
(http://poignantguide.net/ruby).

However, I’m a bit stuck understanding how block arguments work. in his
example:

kitty_toys = [
{:shape => ‘sock’, :fabric => ‘cashmere’},
{:shape => ‘mouse’, :fabric => ‘calico’},
{:shape => ‘eggroll’, :fabric => ‘chenille’}
]

kitty_toys.sort_by { |toy| toy[:shape] }.each do |toy|
puts “Blixy has a #{ toy[:shape] } made of #{ toy[:fabric] }”
end

I know what it does. I put it through irb and it works. But i don’t
understand HOW it works, exactly. Mainly, the toy bit. I don’t quite get
what role it plays in the code and how the code uses it.

I’ve read up online and in both books I have, but, for whatever reason i
STILL cannot grasp block arguments and what role they play.

Maybe I’m just brain farting here, but if anyone could lend some tips on
this I’d appreciate it.

On Feb 7, 2008 3:25 AM, Russell Me [email protected] wrote:

{:shape => ‘mouse’, :fabric => ‘calico’},

I’ve read up online and in both books I have, but, for whatever reason i
STILL cannot grasp block arguments and what role they play.

Maybe I’m just brain farting here, but if anyone could lend some tips on
this I’d appreciate it.

As you may know, “toy” is the argument to block. Block is a special
form of function,
and using this |argument| the function sort_by passes data to the block.

It makes more sense if you put yield in the picture as well. Let’s see
how e.g. upto is implemented:

class Integer
def upto_(limit)
counter = self
while counter <= limit
yield counter
counter += 1
end
end
end

In other words: we do something, and in special places we call the
block function (yield). We pass
the counter as the block argument.

Now we can try the outer view of this thing – we’ll see the block
being called with various numbers:

10.upto_(20) { |counter| puts counter }

And back to your/_why’s example: it’s a chain of several method calls:

  1. we call sort_by with { |toy| toy[:shape] } block on kitty_toys
  2. then we call each with do … end block on the result of step 1.

sort_by uses the block to generate sort index for each item in the
array. The block gets an item,
and returns the index for that item. (in this case, we want to sort_by
toy’s :shape)
sort_by returns sorted array.

Then we call each on the result array. each calls the block with each
item one by one.
So, the do…end block gets called 3 times, once for each item. That
block just prints the item,
as you have noticed.

So, this is my attempt to explain. If it doesn’t make sense, maybe
it’s because it’s 4 AM here :wink:

Jano

Russell Me wrote:

I’m trying to pick up ruby and I’m impressed by all the cool stuff it
does out of the box. I’m reading a few books but i’m finding why’s
poignant guide to ruby to be the most helpful and entertaining
(http://poignantguide.net/ruby).

However, I’m a bit stuck understanding how block arguments work. in his
example:

kitty_toys = [
{:shape => ‘sock’, :fabric => ‘cashmere’},
{:shape => ‘mouse’, :fabric => ‘calico’},
{:shape => ‘eggroll’, :fabric => ‘chenille’}
]

kitty_toys.sort_by { |toy| toy[:shape] }.each do |toy|
puts “Blixy has a #{ toy[:shape] } made of #{ toy[:fabric] }”
end

I know what it does. I put it through irb and it works. But i don’t
understand HOW it works, exactly. Mainly, the toy bit. I don’t quite get
what role it plays in the code and how the code uses it.

I’ve read up online and in both books I have, but, for whatever reason i
STILL cannot grasp block arguments and what role they play.

Maybe I’m just brain farting here, but if anyone could lend some tips on
this I’d appreciate it.

I think of a block as Cookiemonster from Sesame street. When you throw
something at him, he will name it “cookie” and then eat it. In this case
you throw each element of kitty_toys, the block will call them all “toy”
and process them.

I think of a block as Cookiemonster from Sesame street. When you throw
something at him, he will name it “cookie” and then eat it. In this case
you throw each element of kitty_toys, the block will call them all “toy”
and process them.

Unfortunately, my knowledge of Sesame Street is rather limited. But I
think you’re forgetting something. I’m quite sure there is something
or someone sitting between you and the Cookiemonster, let’s call it/
him/her Sorty. Sorty takes all the kitty_toys from you and hands one
toy after the other over to the Cookiemonster. So the Cookiemonster
doesn’t get them all at once but only one at a time. That’s because it
is a well educated Cookiemonster that doesn’t eat two cookies at a
time. Sorty then takes the toys back from the Cookiemonster and hands
them over to Mrs. Each.

Nice analogy.

tho_mica_l wrote:

I think of a block as Cookiemonster from Sesame street. When you throw
something at him, he will name it “cookie” and then eat it. In this case
you throw each element of kitty_toys, the block will call them all “toy”
and process them.

Unfortunately, my knowledge of Sesame Street is rather limited. But I
think you’re forgetting something. I’m quite sure there is something
or someone sitting between you and the Cookiemonster, let’s call it/
him/her Sorty. Sorty takes all the kitty_toys from you and hands one
toy after the other over to the Cookiemonster. So the Cookiemonster
doesn’t get them all at once but only one at a time. That’s because it
is a well educated Cookiemonster that doesn’t eat two cookies at a
time. Sorty then takes the toys back from the Cookiemonster and hands
them over to Mrs. Each.

Nice analogy.

Thank you both for your help. it’s making more sense but i imagine it
should make total sense to me, no?

Still not 100% though about it and I certainly hope this isn’t a preview
of things to come. Things have been going well until i hit this simple
roadblock of understanding.

kitty_toys.sort_by { |toy| toy[:shape] }.each do |toy|
puts “Blixy has a #{ toy[:shape] } made of #{ toy[:fabric] }”
end

ok, so i see that a sort is being performed on kitty toys with
“kitty_toys.sort_by”. but what’s the next bit about? namely: { |toy|
toy[:shape] }.each do |toy| I see that the sort is based on the shape
from toy[:shape] but how? and what is the “|toy|” before it doing? and
then i assume that the .each means do it for all the items, right? and
then… for each toy, output the puts bit? (which then get’s sorted by
the sort_by)?

Sorry to be a bother with something so trivial.

On Feb 7, 2008, at 3:56 PM, Russell Me wrote:

kitty_toys.sort_by { |toy| toy[:shape] }.each do |toy|
puts “Blixy has a #{ toy[:shape] } made of #{ toy[:fabric] }”
end

ok, so i see that a sort is being performed on kitty toys with
“kitty_toys.sort_by”. but what’s the next bit about? namely: { |toy|
toy[:shape] }.each do |toy| I see that the sort is based on the
shape
from toy[:shape] but how?

One thing to keep in mind that the ‘purpose’ of a block depends
entirely on the method that is being called. Syntactically a block
is a block is a block but the semantics depend entirely on how the
method is utilizing the block.

3.times {|x| puts x } # 0 1 2

3 is the object
times is the method
{|x| puts x } is the block associated with the call to times.

In this case, 3.times, ‘yields’ control to the block 3 times. The
first time, 0 is passed as the argument. The second time 1 is passed
as the argument. The third time 2 is passed as the argument.

The times method doesn’t have a clue as to what the block is going to
do. It just knows to yield control to the block three times.

sum = 0
3.times { |x| sum = sum + x }
puts sum

In this example the block is summing the arguments, ‘times’ doesn’t
know that is what the block is doing, it just does its job of
iteration and lets the block do what it wants.

Back to your original example, with a twist

kitty_toys.sort { |t1, t2| t1[:shape] <=> t2[:shape] }

Any sorting algorithm needs to know how to compare two items. By
picking a different comparison procedure you can cause a collection
to be sorted in different ways. From the sorting algorithm’s
perspective nothing changes other than the manner by which any two
items are ‘compared’.

In this example with ‘sort’ (instead of sort_by) it is clear that the
block is given two toys and returns the verdict as to how the two
toys ‘compare’ (by using the comparison operator on the shape
property of the two toys). As sort is making its way through the
collection, it will periodically yield control to the block when it
needs to compare two items. The sort method really doesn’t know
anything at all about the contents of the block it just expects the
block to return -1, 0, or 1 and goes from there.

Switching to sort_by

kitty_toys.sort_by { |toy| toy[:shape] }

This is a slight variation of sort. Instead of the block providing a
way of comparing two elements of the collection, the block is
expected to return the ‘comparable’ characteristic of the element.
So sort_by runs through the entire collection calling the block for
each element and remembering what the block returns for each element.
Now sort_by begins sorting the collection just like ‘sort’ but this
time instead calling out to a comparison block it makes comparisons
by using the comparable ‘characteristic’ that it collected during its
first pass through the collection.

The decision to use sort or sort_by really depends on how expensive
it is to do the comparison.
Sometimes it makes sense to pre-compute the comparison
characteristic, sometimes it doesn’t make sense.

What I’m trying to point out is that in order to understand a block
in any particular situation you must look at the documentation for
the method that is being called. A method may ignore a block, save
it for use later on (like a callback), call it once, or call it many
times. The only way to know how the block is being used is to look
at the documentation for that particular method.

Think of a block as just another argument to a method. It has its
own syntax but it really is just another argument that the method can
use as it wants just as with any ‘regular’ argument.

Gary W.

Okay, I saw I was too slow. So I only add something to the following
point:

but what’s the next bit about? namely: { |toy|
toy[:shape] }.each do |toy|

Let’s break it up. If you don’t understand what’s going, break the
code
in smaller pieces and step through it. Or test it in irb.

The each{} part is a totally different story.

a.sort_by {|n| n}.each {|n| p n}

actually should be read rather like:

a1 = a.sort_by {|n| n}
a2 = a1.each {|n| n}

The period joins these two methods into a chain so that each()
operates
directly on the value of sort_by(), which happens to be the sorted
array.

Or to stick with the Sesame Street’ish analogy: Mrs Each doesn’t care
about the Cookiemonster. That’s Sorty who sees the Cookiemonster. But
Mrs. Each is a grown-up, she cannot see Cookiemonster and thinks such
things are just childish phantasies.

Russell Me wrote:

kitty_toys.sort_by { |toy| toy[:shape] }.each do |toy|
puts “Blixy has a #{ toy[:shape] } made of #{ toy[:fabric] }”
end

ok, so i see that a sort is being performed on kitty toys with
“kitty_toys.sort_by”. but what’s the next bit about? namely: { |toy|
toy[:shape] }.each do |toy| I see that the sort is based on the shape
from toy[:shape] but how? and what is the “|toy|” before it doing? and
then i assume that the .each means do it for all the items, right? and
then… for each toy, output the puts bit? (which then get’s sorted by
the sort_by)?

Sorry to be a bother with something so trivial.

Read the code from left to right -Ruby does too.
“sort_by” knows how to sort, but it does not know what to sort on.
The block { |toy| toy[:shape] } is a simple machine. It gets each
element of Kitty_toys and immediatly puts a label on it, by means of
“|toy|”.(or |Cookie| or whatever). Then it goes to work on this toy- It
gets the :shape from it, and gives it to sort_by. sort_by does it’s
magick, which Gary W. explains better than I can.

The result is an array, sorted on shape.

This (nameless) array is also iterated, this time with .each . This
method .each does not know anything, it just executes the block for each
element . The block again labels each element with “|toy|” . This not
the same thing as the “toy” in de first block, which is finished and
does not exist anymore anyway. “|sorted_toy|” might have been more
clear. Then it goes to work on it:

puts “Blixy has a #{ toy[:shape] } made of #{ toy[:fabric] }”
in which "Puts"does the printing. If it encounters #{ toy[:shape] }
puts pauses the printing and ruby executes what’s in the curly braces.
That’s it.

If you add “p kitty_toys” at the end of the code you’ll see that
kitty_toys is still unsorted. The unnamed sorted array has done it’s
work and disappeared.

Regards,

Siep

You’ve all contributed a great deal of information and I’m glad to be
receiving help versus “RTFM” comments.

kitty_toys.sort_by { |toy| toy[:shape] }.each do |toy|
puts “Blixy has a #{ toy[:shape] } made of #{ toy[:fabric] }”
end

So in this case (with the sort_by) I gather that a sorted array is being
thrown into |toy|, and then for each item in |toy| it’s key and value
are printed out by the puts statement? does that about sum it up? is it
for each item in the array (that is, getting the number 3) or somehow
incrementing through?

and with this…

3.times {|x| puts x }

the output is 0,1,2 because… x is initially nil and a value of 1 is
returned (by… what?) to .times? is that right?

I see that everything uses block arguments differently, which is good to
know.

Anyway, I really do appreciate such a helpful group of folk. It’s
encouraging. Thanks for all your input!

I think it’s kind of funny no one’s pointed this out yet. The anatomy
of a block:
{ |argument, list| code.to(execute) }

A block is built a little like a method, though it has no name and
only exists while it is executing (as others has said). The bits
between pipes are like the argument list in a method and the bits
after that are to be run. Maybe this will help:

def some_method(argument, list)
code.to(execute)
end

See the similarity? Now, the reason the semantics change based on what
method the block is attached to is because each method (not THE each
method) passes a different thing (or set of things) as arguments.
Integer.times passes numbers (as illustrated above). Other methods
pass nothing at all. It’s almost like… passing a little method to
another method as an argument, knowing that the method you’re calling
will execute that code in a certain way (just like you know it’ll do
other stuff to normal arguments you pass in) and give you back
something helpful.

I hope that’s clear. Sometimes I get rambly and don’t actually explain
anything.

Ben

On Feb 7, 2008 11:07 PM, Russell Me [email protected] wrote:

kitty_toys.sort_by { |toy| toy[:shape] }.each do |toy|
puts “Blixy has a #{ toy[:shape] } made of #{ toy[:fabric] }”
end

So in this case (with the sort_by) I gather that a sorted array is being
thrown into |toy|, and then for each item in |toy| it’s key and value
are printed out by the puts statement? does that about sum it up? is it
for each item in the array (that is, getting the number 3) or somehow
incrementing through?

No. sort_by is taking the block and for each item in the array, it
puts that item into |toy|, and then grabs the :shape from it. it
knows, because of it’s nature as sort_by that this is the value you
want compared between all the elements, and so it does so, and returns
the sorted array for .each to be called on. Does that make any sense?
Once you get this, I promise you will love the concept.

Ben

2008/2/7, Day [email protected]:

I think it’s kind of funny no one’s pointed this out yet. The anatomy
of a block:
{ |argument, list| code.to(execute) }

A block is built a little like a method, though it has no name and
only exists while it is executing (as others has said).

I disagree with the “it exists only while it is executing” bit. A
block is an anonymous function and lives as long as regular methods
do. I.e. you declare them, the code is parsed and compiled into an
internal representation and can be invoked any number of times (even
concurrently). The code lives all the time but there is any number
(including 0) of active invocations on them at any given point in time
of program execution.

It’s almost like… passing a little method to
another method as an argument, knowing that the method you’re calling
will execute that code in a certain way (just like you know it’ll do
other stuff to normal arguments you pass in) and give you back
something helpful.

Exactly. A block can be seen as an anonymous callback function.

I hope that’s clear. Sometimes I get rambly and don’t actually explain anything.

I think that was pretty clear.

Kind regards

robert

Russell Me wrote:

3.times {|x| puts x }

the output is 0,1,2 because… x is initially nil and a value of 1 is
returned (by… what?) to .times? is that right?

Perhaps the easiest way is to explain with a method that basically does
the same thing as times:


class Fixnum
def my_times
return if !block_given?
i = 0
while (i < self)
yield(i)
i += 1
end
end
end

3.my_times {|x| puts x }

  • The line “return if !block_given?” is used to prevent crash if the
    method is called without code block.

  • In the case of Fixnum above, “self” is the same as the digit

  • The code block is called by “yield(i)”, but the value of i will be
    named x in your code block.

Best regards,

Jari W.

Robert K. wrote:

It’s almost like… passing a little method to
another method as an argument, knowing that the method you’re calling
will execute that code in a certain way (just like you know it’ll do
other stuff to normal arguments you pass in) and give you back
something helpful.

Exactly. A block can be seen as an anonymous callback function.

…perhaps with one additional twist/feature, compared to callbacks in
more “traditional” languages: Blocks inherit the environment from where
it is defined (the scope is different for a block compared to a
function).

Best regards,

Jari W.

So, after 3 days I still don’t understand this. Is it really that
difficult, or am i just plain dumb?

While I’m looking to understand the kitty_toys sort, it’s really just
because I want to know how it all works.

I think you’ve all explained it well, but you’ve explained it in a way
that only makes sense if you totally get ruby. And I’m not at all there.
It’s been helpful, and I’m certainly closer to understanding.

I have some background in perl and php, but no OOP background, and I’m
trying to pick up ruby.

So if it’s not asking for too much, can someone explain to me how the
kitty toys code works, as if I was a 5 year old? (maybe thrown in some
pictures or 2? :slight_smile: )

even this:
3.times {|x| puts x }

I see it work, I understand what’s going on, but I don’t know HOW it’s
working.

Day wrote:

On Feb 8, 2008 10:22 PM, Russell Me [email protected] wrote:

So, after 3 days I still don’t understand this. Is it really that
difficult, or am i just plain dumb?

It is not exactly a simple concept. Especially, I think, if you’re not
familiar with object oriented thinking.

While I’m looking to understand the kitty_toys sort, it’s really just
because I want to know how it all works.

I think, actually, that _why’s example is pretty complex, so maybe it
would be better for stick with your 3.times example.

even this:
3.times {|x| puts x }

I see it work, I understand what’s going on, but I don’t know HOW it’s
working.

Actually. Maybe let’s make it simpler. Forget, for the moment, about
the |x| bit. Let’s look at this code:

3.times { puts “Arr!” } # Very high seas.

The block, there, is sort of where you store code for a second. So you
wrap up something to be executed (the puts statement in this case) in
a block and you hand it to the times method. Not every method can
accept a block like that, but this one can.

So what the times method does is it executes whatever’s in the block
it got handed a number of times equal to the integer it was called on
(three in this case). It sort of says, in English:
Do ‘puts “Arr!”’ three times.

If you’re entirely new to OOP, it may be hard to remember or envision
this, but: The code does not execute in sequence. Remember that 3 is
an object. It is doing something (the method). It can do that thing,
on stuff that you hand it (a block in this case, but this is true for
all arguments). Really, the key difference between a block and any
other argument you might pass to a method is that a block is code that
can be executed, but the execution is held off until the method it’s
passed to asks it to execute.

Does that make some sense? If you get that alright, then I think it’ll
be a bit easier to move on to the more complicated examples. Kudos, by
the way, for your perseverence. Lesser men would have given up in
frustration by now. I hope you don’t feel like you’re being badgered
or yelled at or ganged up on. Hang in there. You’ll get it.

Ben

Ben,

that actually was helpful. Understanding that the crap inside the block
gets executed 3 times. that makes sense.

the kitty toys thing is simply what why threw at me (the reader). too
complicated? perhaps. it’s the block itself then i don’t get. everything
else i understand, for the most part.

I appreciate the help (and attempts at help) from everyone. this seems
to be a very friendly group. This seems such a trivial simple thing, but
i can’t wrap my little brain around it.

On Feb 8, 2008 10:22 PM, Russell Me [email protected] wrote:

So, after 3 days I still don’t understand this. Is it really that
difficult, or am i just plain dumb?

It is not exactly a simple concept. Especially, I think, if you’re not
familiar with object oriented thinking.

While I’m looking to understand the kitty_toys sort, it’s really just
because I want to know how it all works.

I think, actually, that _why’s example is pretty complex, so maybe it
would be better for stick with your 3.times example.

even this:
3.times {|x| puts x }

I see it work, I understand what’s going on, but I don’t know HOW it’s
working.

Actually. Maybe let’s make it simpler. Forget, for the moment, about
the |x| bit. Let’s look at this code:

3.times { puts “Arr!” } # Very high seas.

The block, there, is sort of where you store code for a second. So you
wrap up something to be executed (the puts statement in this case) in
a block and you hand it to the times method. Not every method can
accept a block like that, but this one can.

So what the times method does is it executes whatever’s in the block
it got handed a number of times equal to the integer it was called on
(three in this case). It sort of says, in English:
Do ‘puts “Arr!”’ three times.

If you’re entirely new to OOP, it may be hard to remember or envision
this, but: The code does not execute in sequence. Remember that 3 is
an object. It is doing something (the method). It can do that thing,
on stuff that you hand it (a block in this case, but this is true for
all arguments). Really, the key difference between a block and any
other argument you might pass to a method is that a block is code that
can be executed, but the execution is held off until the method it’s
passed to asks it to execute.

Does that make some sense? If you get that alright, then I think it’ll
be a bit easier to move on to the more complicated examples. Kudos, by
the way, for your perseverence. Lesser men would have given up in
frustration by now. I hope you don’t feel like you’re being badgered
or yelled at or ganged up on. Hang in there. You’ll get it.

Ben

On Feb 6, 2008 8:25 PM, Russell Me [email protected] wrote:

{:shape => ‘mouse’, :fabric => ‘calico’},

I’ve read up online and in both books I have, but, for whatever reason i
STILL cannot grasp block arguments and what role they play.

Maybe I’m just brain farting here, but if anyone could lend some tips on
this I’d appreciate it.

As others have pointed out, the #sort_by method throws you a
reference (doesn’t have to be called “toy”) and you do whatever you
want with it. What your block should do largely depends upon how
the calling method works.

In this case, #sort_by throws your block object references (one at a
time) and you are supposed to give it back an object reference that is
comparable (i.e. responds to the <=> method).

At least, that’s the way I understand it without reading the underlying
code.

A very simple example…

def simple
yield 3
end

simple {|i| puts i}

Todd

On Feb 8, 2008 11:29 PM, Todd B. [email protected] wrote:

end

simple {|i| puts i}

I should qualify that 3 is not a reference because it’s immutable.
The example was just to illustrate how blocks work on a simplistic
level.

Todd

On 2008-02-09 13:22 +0900 (Sat), Russell Me wrote:

3.times {|x| puts x }

I see it work, I understand what’s going on, but I don’t know HOW it’s
working.

The key point you may be missing is that, unlike blocks in C, a block in
ruby is a code definition; it defines a function. This function is an
object, like any other, and so you can store it, call it later, etc. So:

f = proc { |x| puts(x * 2) }

prints nothing but, f now points to an object representing that
function. (The “proc” is just an artifact of some inconsistent language
design; you don’t need it when a function comes before the block
definition.)

So try calling it:

f.call(0)      # prints "0"
f.call(1)      # prints "2"
f.call(2)      # prints "4"

Now, some functions can take a block and call it multiple times…

3.times(&f)      # prints "0", "2", and "4", just as above

Next step: get yourself a copy of The Little Schemer and work through
it. Then you will achieve much better understanding of many programming
languages, including Ruby.

cjs