Ruby中的块和块之间的区别
为什么有时我应该使用块和其他时间和块在接受块的function?
block
只是一个局部variables, &block
是传递给方法的块的引用。
def foo(block = nil) p block end foo # => nil foo("test") # => test foo { puts "this block will not be called" } # => nil def foo(&block) p block end foo # => nil foo("test") # => ArgumentError: wrong number of arguments (1 for 0) foo { puts "This block won't get called, but you'll se it referenced as a proc." } # => #<Proc:0x0000000100124ea8@untitled:20>
当调用方法将一个proc作为一个块传递给一个方法时,你也可以使用&block
,这样就可以像使用块一样使用proc。
my_proc = proc {|i| i.upcase } p ["foo", "bar", "baz"].map(&my_proc) # => ["FOO", "BAR", "BAZ"] p ["foo", "bar", "baz"].map(my_proc) # => ArgumentError: wrong number of arguments (1 for 0)
variables名称block
并不意味着什么特别的。 如果你喜欢,你可以使用&strawberries
,这里的&符号是关键。
您可能会发现这篇文章有帮助。
在一个参数列表中, &whatever
是传递给该方法的块,还是将其包装在一个Proc对象中。 Proc被存储在一个叫做whatever
的variables中(当然可以是你在&符号之后键入的任何名字 – 通常是“block”)。 在一个方法调用之后, &whatever
语句把一个Proc变成一个块。 所以如果你这样定义一个方法:
def thing(&block) thing2 &block end
你正在定义一个方法,它需要一个块,然后用该块调用另一个方法。
如果不设置&before块,Ruby将不会识别它与传递给函数的“块”的关系。 这里有一些例子。
def f(x, block); end f(3) { 2+2 } # gives an error, because "block" is a # regular second argument (which is missing) def g(x, &block); end g(3) { 2+2 } # legal def h(x); end h(3) { 2+2 } # legal
以后在一个函数中使用:
def x(&block) # x is a 0 param function y(block) # y is a 1 param function (taking one "Proc") z(&block) # z is a 0 param function (like x) with the block x received end
所以,如果你调用z(&block)
那么(近!!)就像调用z { yield }
:你只需将该块传递给下一个函数。