From: Phrogz Date: 2007-02-08T00:00:06+09:00 Subject: Re: Question about closure example on p. 56 of pickaxe book On Feb 6, 10:41 pm, "Alex Strasheim" 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')?