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方法。 –