我刚刚完成了Ruby Koans,使用Object.send调用方法的单元和方法上的Ruby文档都没有提供有关在send方法中使用块的任何信息。将附加到send方法的块传递给它调用的方法,还是块会丢失?
示例:
foo.send(:a_method) { bar.another_method }
答案 0 :(得分:21)
documentation对此有点不清楚:
发送(符号[,args ...])→obj
调用 symbol 标识的方法,并将指定的参数传递给它。
但请注意指定的任何参数部分。您为方法提供的块实际上是一种有趣的隐式参数,因此您可以执行以下操作:
def m(&b)
@a.each(&b)
end
m { |e| puts e }
将块作为Proc实例传递。但是,您也可以这样做:
def m
yield
end
m { puts 'pancakes' }
所以就参数列表而言,块是特殊的,但即使有时是隐式的,该块仍然表现为参数。
鉴于上面的“块是一种参数”漫无目的以及Ruby中块的重要性,send
传递块是合理的。您也可以尝试一下,但是您必须通过“尝试”方法来注意意外和无证的行为:
class C
def m
yield
end
end
o = C.new
o.send(:m) { puts 'pancakes' }
# "pancakes" comes out
答案 1 :(得分:14)
是。请考虑以下事项:
class A
def explicit(&b); b; end
def implicit; yield "hello"; end
end
>> A.new.send(:explicit) { }
=> #<Proc:0x0000000000000000@(irb):19>
>> A.new.send(:implicit) { |greeting| puts greeting }
hello
=> nil
希望这有帮助!
答案 2 :(得分:5)
是的,它会的。在方法内,您可以使用block_given?
进行检查,然后使用yield
class Foo
def bar
puts "before yield"
yield if block_given?
puts "after yield"
end
end
f = Foo.new
f.send(:bar)
puts ""
f.send(:bar) { puts "yield"}
before yield
after yield
before yield
yield
after yield
答案 3 :(得分:1)
TL; DR:是的, Volume Date Open High Low Close Adj
Date
2009 0 2009-12-31 31.709999 31.840000 31.299999 1957700 23.547892
2010 1 2010-01-04 31.480000 31.840000 31.330000 3472500 23.668222
2010 4 2010-01-07 31.549999 31.700001 31.049999 7232100 23.487726
方法会将闭包传递给它调用的方法。
在幕后,提供给方法调用的闭包将作为附加参数(尽管是一个特殊的参数)隐式传递给该方法。您可以使用send
...
call
...或隐式包含> def do_it(&block)
> block.call
> end
=> :do_it
> do_it { puts 'apples' }
apples
=> nil
。
yield
您可以将闭包传递给任何方法,包括> def do_it_with_yield
> yield if block_given?
> end
=> :do_it_with_yield
> do_it_with_yield { puts 'bananas' }
bananas
=> nil
,:send
等,尽管取决于是否使用闭包。
在:public_send
等人的情况下,他们按照我们希望和期望的方式忠实地通过了闭包。
send
例如,在实现> self.public_send(:do_it) { puts 'cherries' }
cherries
=> nil
> self.send(:do_it_with_yield) { puts 'dates' }
dates
=> nil
方法时,这一点很重要。
method_missing
参考: