2014-05-12 31 views

回答

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 
  1. 我們在特殊塊槽傳遞:to_s。這由&表示。
  2. 使用&在符號上調用to_proc
  3. to_proc返回Proc,它將:to_s發送到第一個參數。
  4. 然後將這個Proc傳遞給特殊塊槽中的map方法。
  5. 產生的每個元素都成爲消息的接收者。

這是相當多的等價於:

enumerable.map { |receiver| receiver.send :to_s } 

¹耶胡達·卡茨。 Ruby不是一個可調用語言(它是面向對象的)。 Blog post