# Question about closure example on p. 56 of pickaxe book

**URL:** <https://www.ruby-forum.com/t/question-about-closure-example-on-p-56-of-pickaxe-book/84721>\
**Category:** Ruby\
**Created:** [February 7, 2007, 6:45am UTC](https://www.ruby-forum.com/t/question-about-closure-example-on-p-56-of-pickaxe-book/84721 "2007-02-07T06:45:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![asoto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/58956e/32.png) [@asoto](https://www.ruby-forum.com/u/asoto)\
**Post date:** [February 7, 2007, 6:45am UTC](https://www.ruby-forum.com/t/question-about-closure-example-on-p-56-of-pickaxe-book/84721/1 "2007-02-07T06:45:52Z")

</div>

I’m new to both Ruby and closures, and I’m trying to nail down exactly  
what’s going on in an example on p. 56 in the 2nd edition of  
Programming Ruby:

songlist = SongList.new

class JukeboxButton \< Button

```
def initialize(label, &action)
  super(label)
  @action = action
end

def button_pressed
  @action.call(self)
end

```

end

start\_button = JukeboxButton.new(“Start”) { songlist.start }  
pause\_button = JukeboxButton.new(“Pause”) {songlist.pause }

(I typed this in manually, so if there are typos, they come from me,  
and not the book.)

I understand that @action is an instance variable that points to a  
Proc object containing the block of code in the curly brackets. And I  
think I understand the idea that the context of the block is saved  
along with the code in the Proc object.

What I don’t understand is why we need the parameter “self” in:

@action.call(self)

When someone presses the start button, that generates a call to  
start\_button.button\_pressed, right? So when we run that method, we do  
@action.call, which would songlist.start to run.

Why do we need “self”? Doesn’t “self” refer to start\_button, which is  
an instance of JukeboxButton? Why would songlist need to know about  
the button?

And if we were going to pass a parameter when we run @action.call,  
wouldn’t the block of code need to have a parameter in it? Like this:

start\_button = JukeboxButton.new(“Start”) { |x| songlist.start }

I realize that doesn’t make sense – the parameter isn’t used in that  
code block. But I’m pretty confused by what’s going on here.

Thanks (and I hope this isn’t too dumb, or inappropriate.)

---

<div class="post-metadata">

**Author:** ![asoto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/58956e/32.png) [@asoto](https://www.ruby-forum.com/u/asoto)\
**Post date:** [February 7, 2007, 7:12am UTC](https://www.ruby-forum.com/t/question-about-closure-example-on-p-56-of-pickaxe-book/84721/2 "2007-02-07T07:12:53Z")

</div>

On 2/7/07, Alex S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> @action = action
> 
> ```
> 
> @action.call(self)  
> wouldn’t the block of code need to have a parameter in it? Like this:
> 
> start\_button = JukeboxButton.new(“Start”) { |x| songlist.start }
> 
> I realize that doesn’t make sense – the parameter isn’t used in that  
> code block. But I’m pretty confused by what’s going on here.
> 
> Thanks (and I hope this isn’t too dumb, or inappropriate.)

Your question is understandable, and it’s a bit odd that they pass  
self as an parameter since it’s not used at all.  
My advice: ignore it.  
Might be something that slipped through the final review or something.  
There is no hidden meaning and it works perfectly without passing  
self.

Hope that clears things up,  
^ manveru

---

<div class="post-metadata">

**Author:** ![asoto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/58956e/32.png) [@asoto](https://www.ruby-forum.com/u/asoto)\
**Post date:** [February 7, 2007, 4:00pm UTC](https://www.ruby-forum.com/t/question-about-closure-example-on-p-56-of-pickaxe-book/84721/3 "2007-02-07T16:00:52Z")

</div>

On Feb 6, 10:41 pm, “Alex S.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> And if we were going to pass a parameter when we run @action.call,  
> wouldn’t the block of code need to have a parameter in it? Like this:
> 
> start\_button = JukeboxButton.new(“Start”) { |x| songlist.start }

Michael answered the brunt of your question as I would have (“ignore  
the self”), but I wanted to answer the above question of yours.

While methods in Ruby are pretty adamant about getting exactly the  
number of parameters you define (except when you explicitly provide  
default values or explicitly ask to collect any ‘extra’ values into an  
array), blocks are much more forgiving. See the following code:

def block\_to\_proc( &blok )  
blok  
end

no\_arg = block\_to\_proc{ ‘foo’ }  
one\_arg = block\_to\_proc{ |x| “foo-#{x.inspect}” }  
only\_one\_used = block\_to\_proc{ |x,y| “foo-#{x.inspect}” }  
two\_arg\_used = block\_to\_proc{ |x,y| “foo-#{x.inspect}-  
#{y.inspect}” }

puts no\_arg.call  
#=\> foo

puts no\_arg.call( ‘bar’ )  
#=\> foo

puts one\_arg.call  
#=\> warning: multiple values for a block parameter (0 for 1)  
#=\> foo-nil

puts one\_arg.call( ‘bar’ )  
#=\> foo-“bar”

puts one\_arg.call( ‘bar’, ‘jim’ )  
#=\> foo-[“bar”, “jim”]  
#=\> warning: multiple values for a block parameter (2 for 1)

puts only\_one\_used.call  
#=\> foo-nil

puts only\_one\_used.call( ‘bar’ )  
#=\> foo-“bar”

puts only\_one\_used.call( ‘bar’, ‘jim’ )  
#=\> foo-“bar”

puts only\_one\_used.call( ‘bar’, ‘jim’, ‘jam’ )  
#=\> foo-“bar”

puts two\_arg\_used.call  
#=\> foo-nil-nil

puts two\_arg\_used.call( ‘bar’ )  
#=\> foo-“bar”-nil

puts two\_arg\_used.call( ‘bar’, ‘jim’ )  
#=\> foo-“bar”-“jim”

puts two\_arg\_used.call( ‘bar’, ‘jim’, ‘jam’ )  
#=\> foo-“bar”-“jim”

Note that the above behaves the same if you use Proc.new instead of  
the block\_to\_proc function. In 1.8.6, if you use ‘proc’ or ‘lambda’  
instead, the no\_arg and one\_arg examples work the same, but you get an  
ArgumentError (“wrong number of arguments (0 for 2)”) raised and  
halting your program when you try to call only\_one\_used without any  
arguments. (And if you comment that out, you also get that same error  
when you try to call it with too many arguments.)

I provide the above without any justification for the behavior. 🙂  
This is with Ruby 1.8.6.

My own question: what rationale allows the one-argument Proc ‘auto-  
splat’ the extra arguments into an array, but the two-argument case  
does not? And what changes in 1.9 (besides ‘proc’ becoming another way  
of performing ‘Proc.new’ instead of ‘lambda’)?

---

<div class="post-metadata">

**Author:** ![asoto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/58956e/32.png) [@asoto](https://www.ruby-forum.com/u/asoto)\
**Post date:** [February 7, 2007, 4:05pm UTC](https://www.ruby-forum.com/t/question-about-closure-example-on-p-56-of-pickaxe-book/84721/4 "2007-02-07T16:05:53Z")

</div>

On Feb 7, 12:11 am, “Michael F.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Your question is understandable, and it’s a bit odd that they pass  
> self as an parameter since it’s not used at all.  
> My advice: ignore it.  
> Might be something that slipped through the final review or something.  
> There is no hidden meaning and it works perfectly without passing  
> self.
> 
> Hope that clears things up,

It does… I was afraid it was some sort of strange Proc magic that I  
didn’t understand.

Thanks very much

---

<div class="post-metadata">

**Author:** ![asoto](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/58956e/32.png) [@asoto](https://www.ruby-forum.com/u/asoto)\
**Post date:** [February 7, 2007, 4:56pm UTC](https://www.ruby-forum.com/t/question-about-closure-example-on-p-56-of-pickaxe-book/84721/5 "2007-02-07T16:56:59Z")

</div>

On Feb 7, 8:56 am, “Phrogz” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Michael answered the brunt of your question as I would have (“ignore  
> the self”), but I wanted to answer the above question of yours.
> 
> While methods in Ruby are pretty adamant about getting exactly the  
> number of parameters you define (except when you explicitly provide  
> default values or explicitly ask to collect any ‘extra’ values into an  
> array), blocks are much more forgiving. See the following code:

[…]

Thanks very much for taking the time to type that out. It’s really  
helpful.

> My own question: what rationale allows the one-argument Proc ‘auto-  
> splat’ the extra arguments into an array, but the two-argument case  
> does not? And what changes in 1.9 (besides ‘proc’ becoming another way  
> of performing ‘Proc.new’ instead of ‘lambda’)?

I’ll be curious to read what’s said about that as well.
