2015-08-14 41 views
0

我發現this question下這段代碼,如果任何參數傳遞給方法,該方法檢查:可選參數語法

def foo(bar = (bar_set = true; :baz)) 
    if bar_set 
    # optional argument was supplied 
    end 
end 

什麼; :baz在此默認值的目的,並在我會用什麼樣的情況下它?

+0

編寫代碼打印'bar'(也可能是'bar_set'),然後用零參數調用'foo',然後用一個調用。 – cremno

+0

非常有教育意義,謝謝。 – npresco

回答

1

想法是,只有當值不傳遞給參數bar時,纔會評估= (bar_set = true; :baz)

在Ruby中,多個連續表達式的返回值是最後一個表達式的值。因此,= (bar_set = true; :baz)將值true指定爲bar_set,然後將:baz設置爲bar的值(因爲括號中的代碼將計算爲:baz,它是最後一個表達式)。

如果參數通過了,bar_set將是nil並且bar的值將是任何給出的值。

+0

非常感謝! – npresco

+0

這是必要的,因爲無論您用作默認值的值是否也可以由調用者傳遞,所以通過查看值是否通過參數是不可能的。但是一種方法可能想知道這一點。例如,如果你有一個允許非常快的摺疊的自定義集合,你可能想重寫'Enumerable#inject',但是它的契約非常複雜,它基本上有4個「重載」。這對於YARV,JRuby和co來說並不是問題,因爲它們使用C或Java實現,因此可以有權訪問VM,但在Ruby中,您需要這樣的技巧。 –

+0

:-D我剛剛注意到啓發這個問題的答案是我的:-D –