Following article提供Ruby中使用的“&”一个很好的解释:
的隐性块 方法在Ruby中可以使用参数在各种有趣的方式。一个特别有趣的例子是Ruby方法占用一个块。
事实上,所有Ruby方法可以隐含采取的块,而不需要在参数列表中指定这个或具有到方法体例如内使用块:
def hello
end
hello do
puts "hello"
end
这将不执行任何麻烦,但绝对不会因为我们不执行,我们正在传递块被打印出来,我们可以 - 当然 - 很容易被yielding
执行块吧。
def hello
yield if block_given?
end
hello do
puts "hello"
end
氏的时候,我们得到一些输出:
hello
我们yielded
的方法内的块,但事实证明,该方法需要一个块还是隐含的。
它变得更有趣,因为Ruby允许将任何对象传递给方法,并让该方法尝试将此对象用作其块。如果我们在方法的最后一个参数前加一个&符号,Ruby会尝试把这个参数作为方法的块。如果参数已经是Proc对象,则Ruby将简单地将其与该方法关联为其块。
def hello
yield if block_given?
end
blah = -> {puts "lambda"}
hello(&blah)
lambda
如果参数不是Proc
,红宝石会尝试与方法,其块关联之前将其转换成一个(通过调用它to_proc)。
def hello
yield if block_given?
end
class FooBar
def to_proc
-> {puts 'converted lambda'}
end
end
hello(&FooBar.new)
converted lambda
所有这些看起来都很清楚,但是如果我想采用与方法关联的块并将其传递给另一个方法呢?我们需要一种方法来引用我们的区块。
显式模块 当我们编写我们的方法定义时,我们可以明确声明我们期望这个方法有可能取得一个块。令人困惑的是,红宝石使用符号此还有:
def hello(&block)
yield if block_given?
end
hello do
puts "hello"
end
定义我们的方法这种方式,给了我们,使我们可以参考我们的块方法体中的名称。而且,由于我们的块是Proc
对象,而不是yielding
它,我们可以call
它:
def hello(&block)
block.call if block_given?
end
hello do
puts "hello"
end
我喜欢block.call
,而不是yield
,它使事情更清晰。当然,当我们定义我们的方法时,我们不必使用名称'block',我们可以这样做:
def hello(&foo)
foo.call if block_given?
end
hello do
puts "hello"
end
说了这么多, '块'是一个很好的约定。
我相信它会对返回的东西调用to_proc方法。 –