以这种方式将块传递给方法时会调用什么:.map(&:capitalize)
?
它只是语法糖吗?速记?你能用它做任何其他事吗?
答案 0 :(得分:2)
Ruby中的每个方法都有一个特殊的“块”插槽,这不是一个普通的参数。这是因为将一个块恰好传递给一个方法是最常见的用例,Ruby会优化它¹。 &
符号用于表示在该插槽内特定传递的内容。
def with_regular_argument(block)
block.call
end
def with_block_argument(&block)
block.call
end
with_regular_argument lambda { puts 'regular' } # regular
with_block_argument { puts 'block argument' } # block argument
调用方法时也可以使用该符号。这样,您可以将任何对象作为块传递,并在其上调用to_proc
以将其强制转换为Proc
。
def to_proc
proc { puts 'the main object was converted to a Proc!' }
end
with_block_argument &self # the main object was converted to a Proc!
请注意,如果您调用了with_regular_argument
:
begin
with_regular_argument self
rescue => error
puts error.message # undefined method `call' for main:Object
end
Symbol
类实现to_proc
。它基本上是这样的:
class Symbol
def to_proc
proc { |receiver| receiver.send self }
end
end
那么,以下几行如何运作?
enumerable.map &:to_s
:to_s
。这由&
表示。&
来电to_proc
。to_proc
返回Proc
,将:to_s
发送到第一个参数。Proc
传递给特殊块广告位中的map
方法。它几乎相当于:
enumerable.map { |receiver| receiver.send :to_s }
¹耶胡达卡茨。 Ruby不是面向可调用的语言(它是面向对象的)。 Blog post