2014-10-27 82 views
2

有沒有一種方法可以使參數真正成爲可選參數,因此我知道它是否由調用者設置?如何在Ruby 2.0中傳遞可選的命名參數

使用參數nil作爲默認值不起作用,因爲無法知道調用者是否通過了nil或者它是參數的默認值。

命名的參數之前,用Ruby 1.9,使用選項哈希:

def foo(options = {}) 
    # … 
    bar(options) 
end 

def bar(options = {})  
    puts options.fetch(:name, ‘unknown’) # => 'unknown' 
end 

使用Ruby 2.0命名參數:

def foo(name: nil) 
    # … 
    bar(name: name) 
end 

def bar(name: ‘unknown’) 
    # … 
    puts name # => nil, since nil is explicitly passed from `foo` 
end 
+0

標題和問題似乎不匹配。此外,您的代碼顯示的內容並不清楚。 – sawa 2014-10-27 15:52:40

+0

我想我的觀點是,沒有可選參數這樣的事情,接下來最好的事情是將默認設置爲'nil'。但問題是,顯式傳遞nil作爲參數不會調用默認值。 – Kris 2014-10-27 17:01:01

+0

我冒昧地編輯你的標題以更好地反映你的問題。 – 2014-10-27 19:06:07

回答

2

可能是最好的方式是:

def bar(name: nil) 
    name ||= 'unknown' 
    puts name 
end 
+0

這是我發佈該問題後不久發佈的解決方案,我會在接受之前看看是否有其他問題出現。 – Kris 2014-10-27 17:01:38

+0

這樣做的行爲與使用'fetch'不同,因爲顯式傳遞'nil'或'false'的處理方式不同。 – 2014-10-28 16:57:35

1

這並不完全清楚爲什麼你想知道是否提供了論點。知道最有用的理由是因爲你想要一個可選的參數。如果這是原因,那麼從Ruby 2.1開始,你可以得到你想要的。

def foo(a:,b:nil,c:3) 
[a, b, c] 
end 

foo a: 1, b: 2, c: 3 
#=> [1, 2, 3] 
foo a: 1, b: 2 
#=> [1, 2, 3] 
foo a: 1 
#=> [1, nil, 3] 
foo 
#ArgumentError: missing keyword: a 
+0

我認爲問題是'foo(a:1,b:nil)=> [1,nil,3]'和'foo(a:1)=> [1,nil,3]'。有沒有辦法讓'foo'知道它被調用的方式? – 2014-11-01 06:12:25

+0

正確,我明白這是問題所在。解決方案是不給一個默認值(從Ruby 2.1開始是有效的)。通過不給予默認,你堅持提供一個(他們提供的可以是零)。我用'a'參數作爲例子。 – 2014-11-03 21:36:50

0

我就從你的例子,你是不是使用fooname,但要沿着傳遞承擔。

你都應該使用catch命名參數,而不是:

def foo(**named) 
    # … 
    bar(**named) 
end 

def bar(name: ‘unknown’) 
    # … 
    puts name 
end 

foo # => 'unknown' 
foo(name: 'baz') # => 'baz' 

注意,這不是與其他參數(指名)干擾,因此如果您有其他論據foo

def foo(what, other: 42, **named)