From: John Feminella Date: 2011-07-05T01:37:04+09:00 Subject: Re: Are blocks objects? What messages can they handle? That is a fair point, Robert. I didn't use block_given? because I wanted to show that indeed, `block` is an object by the time you can see it in the method. Using "if block_given?" might not have made that clear, but I thought that writing "if block" makes it unambiguous that `block` is a real object with its own semantics. ~ jf -- John Feminella Principal Consultant, BitsBuilder LI: http://www.linkedin.com/in/johnxf SO: http://stackoverflow.com/users/75170/ On Mon, Jul 4, 2011 at 11:54, Robert Klemme wrote: > On Sun, Jul 3, 2011 at 5:15 PM, Stephen Boesch wrote: >> John, >>    although I was not original question author, wanted to thank you for >> that great explanation and example. > > Just one point of nitpicking: > >> 2011/7/3 John Feminella >> >>> A block is a syntactical construct, not an object. A Proc is the >>> object-ized form of a block. If you want to do something on the block, >>> you need to turn it into an object first. >>> >>> An analogy might be that the string "def" is a syntactical construct >>> that creates a method, but it is not itself an object. You can't write >>> "def.(...)" and have it be meaningful in this context. >>> >>> > So . . . how does one send a message to the block before it is passed as >>> > an argument?  Is that even possible? >>> >>> You could make it a Proc first and pass that instead. For example, say >>> you have a method which passes some arguments to a block: >>> >>> ====== >>> > def execute(*args, &block); yield *args if block; end >>>  => nil > > I'd rather use these in pairs because the conversion of a block to an > accessible object has some overhead: > > - block_given? and yield > - &b and b[] / b.call > > So either > > def execute(*args) >  yield *args if block_given? > end > > or > > def execute(*args, &block) >  block[*args] if block > end > > respectively > > def execute(*args, &block) >  block.call(*args) if block > end > > Usually you only need the form with &block if you need to store the > block or pass it on to another method, e.g. > > def foo >  yield 123 > end > > def bar(&b) >  foo(&b) # pass on > end > > bar {|x| p x} # will print 123 > > Kind regards > > robert > > -- > remember.guy do |as, often| as.you_can - without end > http://blog.rubybestpractices.com/ > >