我會一次拿這一個。完全脫離method_missing
,因爲這隻會讓人感到困惑。這實際上完全沒有關係。
splat *
有2件事。在方法定義的參數中,它將多個參數吸收到一個數組中。當在方法調用中使用時,它將數組劃分爲單獨的參數。使用這兩種方法可以將任意數量的參數轉發給其他方法。
def foo(*args)
bar(*args)
end
def bar(a, b, c)
puts a
puts b
puts c
end
foo(1,2,3) # prints 1, 2 and then 3
由於您基本上是轉發所有參數,這是相同的模式。
&
用於塊參數。每個方法調用都可以有其中的一個,它是掛起的塊。這是一個特殊的論點,因爲它不直接引入論證。通過捕獲添加&someblock
作爲方法定義中的最後一個參數,可以將該塊捕獲到變量。
然後,您可以使用相同的語法在方法調用中傳遞一個塊。
def foo(&block)
bar(&block)
end
def bar
yield
end
foo { puts 'hello' } # prints hello
這允許您將掛塊傳遞給另一個方法,而不用調用它。它並不總是需要的,因爲通常只需使用yield
來執行通過的任何塊。但是,如果除了執行它之外還想執行某些操作,則需要捕獲對塊本身的引用。
所以,如果你把這些兩件事情,你得到的終極方法轉發器。您可以捕獲所有任意數量的參數以及任何掛起的塊,然後將其發送給其他方法。
# forwards everything to the method `bar`
def foo(*args, &block)
bar(*args, &block)
end
最後,send
是只是一個方法。它需要一個方法的名稱,後面跟着任意數量的參數(不是數組),並且可以選擇處理掛起的塊。
換句話說:
foo.send methodName, *args, &block
注意,圖示並不僅僅適用於方法的參數定義/參數列表。它也適用於塊參數定義/參數列表,*和*賦值。 –