From: Robert Klemme Date: 2011-03-13T22:20:35+09:00 Subject: Re: send() with a block? On 12.03.2011 22:50, Sean O'Halpin wrote: > On Sat, Mar 12, 2011 at 9:11 PM, Peter Zotov wrote: >> On Sun, 13 Mar 2011 06:01:31 +0900, Sean O'Halpin wrote: >>> >>> On Sat, Mar 12, 2011 at 8:45 PM, 7stud -- wrote: >>>> >>>> Why don't the ruby docs say that send() can take a block? >>>> >>>> Kernel.send(:define_method, :my_meth) do |x| >>>> puts x >>>> end >>>> >>> >>> It's not the send() that's consuming the block - it's the define_method(). >>> >> >> But send() still bothers to pass the block around. Consider the following >> code: >> >> ---8<---8<--- >> def my_method >> p block_given? >> end >> >> def my_send # imitating send >> my_method >> end >> >> my_send # => false >> ---8<---8<--- >> >> -- >> WBR, Peter Zotov. >> >> > > I'm not sure what you're showing me here. But consider this: > > class Foo > def self.send(*a,&block) > p block_given? > super(*a) > end > end > > class Bar > def self.send(*a) > p block_given? > super(*a) > end > end > > Foo.send(:define_method, :my_method) do |x| > p x > end > > block = proc{ |x| p x } > Bar.send(:define_method, :my_method2,&block) > > foo = Foo.new > foo.my_method(1) > bar = Bar.new > bar.my_method2(2) > > def my_method(x) > p x > end > > my_method(10,&block) > > __END__ > true > true > 1 > 2 > 10 > > Even when you explicitly do /not/ pass on the block (as in the > super(*a) call above), send() does not consume it. Automatic propagation of the block is not a feature of #send but a feature of "super": >> class X >> def a;p block_given? end >> def b;p block_given?;a end >> def c;p block_given?;send(:a) end >> end => nil >> X.new.a {1+2} true => true >> X.new.b {1+2} true false => false >> X.new.c {1+2} true false => false >> class A >> def a;p block_given? end >> end => nil >> class B < A >> def a;p block_given?;super end >> end => nil >> class C < A >> def a;p block_given?;super() end >> end => nil >> A.new.a {1+2} true => true >> B.new.a {1+2} true true => true >> C.new.a {1+2} true true => true > Passing a block using the&block syntax is simply part of ruby's > method calling syntax. > A method does not have to specify that it takes a block for you to > call it with one. Correct. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/