2013-05-01 326 views
4

默認值可選參數我想創建一個具有可選參數的默認值與紅寶石

def my_function(a = nil, b=nil, c=500) 

end 

,並調用與參數的函數的功能,我想只指定

my_function(b=100) 

如何在Ruby 1.9.2中完成此操作?

回答

6

你不能在Ruby < 2.0中那樣做(或類似的)。你可以做的最好的是:

def my_function(h = {}) 
    h[:c] ||= 500 
    # Use h[:a], h[:b], h[:c] 
    ... 
end 

my_function(b: 100) 
+2

-1。這是錯誤的。您可以根據需要選擇多個可選參數,而且不必是最後一個。 'def foo(mand1,mand2,opt1 =:opt1,opt2 =:opt2,* splat,mand3,mand4,&block)p local_variables.map {| v | 「#{v} =#{eval(v.to_s)}」} end'非常好。 – 2013-05-02 00:28:17

+1

@JörgWMittag對。我錯了。我將刪除該部分。 – sawa 2013-05-02 05:41:02

+0

@JörgWMittag我認爲一些舊版本的Ruby確實需要參數的默認值是,如果不是最後的話,至少在所有「普通」參數之後。 – 2016-08-16 14:50:08

8

所以你試圖實現關鍵字參數?這應該是Ruby 2.0中的一個新功能,但您可以嘗試在1.9.x中用參數散列來模仿它。 Here's a post,討論瞭如何實現這個目標,這給下​​面的代碼示例:

def foo(options = {}) 
    options = {bar: 'bar'}.merge(options) 
    puts "#{options[:bar]} #{options[:buz]}" 
end 

foo(buz: 'buz') # => 'bar buz' 
+9

請勿創建僅包含指向答案鏈接的答案。 *當鏈接中斷時,您的回答是否有用?相反,總結該答案的相關部分。 – 2013-05-01 18:16:34

+1

鏈接中斷 – 2017-05-29 13:06:35

22

參數綁定到的參數是這樣的:

  1. 只要有未綁定的強制參數在的開始參數列表,從左到右綁定參數
  2. 只要在參數列表末尾有未綁定的強制參數,從右到左綁定參數
  3. 任何剩餘參數都綁定到opti左到右Onal地區參數
  4. 任何剩餘的參數被收集到一個數組並結合到圖示參數
  5. 的塊被纏繞成Proc和如果存在任何未結合的參數綁定到塊參數
  6. 或剩餘的參數,raiseArgumentError

下面是一個例子:

def foo(mand1, mand2, opt1=:opt1, opt2=:opt2, *splat, mand3, mand4, &block) 
    p local_variables.map {|v| "#{v} = #{eval(v.to_s)}" } 
end 

foo 1, 2, 3 
# ArgumentError: wrong number of arguments (3 for 4+) 

foo 1, 2, 3, 4 
# mand1 = 1 
# mand2 = 2 
# opt1 = opt1 
# opt2 = opt2 
# splat = [] 
# mand3 = 3 
# mand4 = 4 
# block = 

foo 1, 2, 3, 4, 5 
# mand1 = 1 
# mand2 = 2 
# opt1 = 3 
# opt2 = opt2 
# splat = [] 
# mand3 = 4 
# mand4 = 5 
# block = 

foo 1, 2, 3, 4, 5, 6 
# mand1 = 1 
# mand2 = 2 
# opt1 = 3 
# opt2 = 4 
# splat = [] 
# mand3 = 5 
# mand4 = 6 
# block = 

foo 1, 2, 3, 4, 5, 6, 7 
# mand1 = 1 
# mand2 = 2 
# opt1 = 3 
# opt2 = 4 
# splat = [5] 
# mand3 = 6 
# mand4 = 7 
# block = 

foo 1, 2, 3, 4, 5, 6, 7, 8 do end 
# mand1 = 1 
# mand2 = 2 
# opt1 = 3 
# opt2 = 4 
# splat = [5, 6] 
# mand3 = 7 
# mand4 = 8 
# block = #<Proc:[email protected](pry):42> 

所以,你可以看到從上面的第3步和示例都可以看出,不能這樣做,因爲可選參數是從左到右綁定的,但是您想指定中間參數。

請注意,這對API設計有影響:您應該設計參數列表,使得最「不穩定」的可選參數(即用戶最可能想要提供的參數)是最靠左的。

紅寶石2.0現在有關鍵字參數,這是你在尋找什麼:

def foo(m1, m2, o1=:o1, o2=:o2, *s, m3, m4, key1: :key1, key2: :key2, **keys, &b) 
    puts local_variables.map {|v| "#{v} = #{eval(v.to_s)}" } 
end 

foo 1, 2, 3 
# ArgumentError: wrong number of arguments (3 for 4+) 

foo 1, 2, 3, 4 
# m1 = 1 
# m2 = 2 
# o1 = o1 
# o2 = o2 
# s = [] 
# m3 = 3 
# m4 = 4 
# key1 = key1 
# key2 = key2 
# b = 
# keys = {} 

foo 1, 2, 3, 4, 5 
# m1 = 1 
# m2 = 2 
# o1 = 3 
# o2 = o2 
# s = [] 
# m3 = 4 
# m4 = 5 
# key1 = key1 
# key2 = key2 
# b = 
# keys = {} 

foo 1, 2, 3, 4, 5, 6 
# m1 = 1 
# m2 = 2 
# o1 = 3 
# o2 = 4 
# s = [] 
# m3 = 5 
# m4 = 6 
# key1 = key1 
# key2 = key2 
# b = 
# keys = {} 

foo 1, 2, 3, 4, 5, 6, 7 
# m1 = 1 
# m2 = 2 
# o1 = 3 
# o2 = 4 
# s = [5] 
# m3 = 6 
# m4 = 7 
# key1 = key1 
# key2 = key2 
# b = 
# keys = {} 

foo 1, 2, 3, 4, 5, 6, 7, 8 
# m1 = 1 
# m2 = 2 
# o1 = 3 
# o2 = 4 
# s = [5, 6] 
# m3 = 7 
# m4 = 8 
# key1 = key1 
# key2 = key2 
# b = 
# keys = {} 

foo 1, 2, 3, 4, 5, 6, 7, 8, key1: 9 
# m1 = 1 
# m2 = 2 
# o1 = 3 
# o2 = 4 
# s = [5, 6] 
# m3 = 7 
# m4 = 8 
# key1 = 9 
# key2 = key2 
# b = 
# keys = {} 

foo 1, 2, 3, 4, 5, 6, 7, 8, key1: 9, key2: 10 
# m1 = 1 
# m2 = 2 
# o1 = 3 
# o2 = 4 
# s = [5, 6] 
# m3 = 7 
# m4 = 8 
# key1 = 9 
# key2 = 10 
# b = 
# keys = {} 

foo 1, 2, 3, 4, 5, 6, 7, 8, key1: 9, key2: 10, key3: 11 
# m1 = 1 
# m2 = 2 
# o1 = 3 
# o2 = 4 
# s = [5, 6] 
# m3 = 7 
# m4 = 8 
# key1 = 9 
# key2 = 10 
# b = 
# keys = {:key3=>11} 

foo 1, 2, 3, 4, 5, 6, 7, 8, key1: 9, key2: 10, key3: 11, key4: 12 do end 
# m1 = 1 
# m2 = 2 
# o1 = 3 
# o2 = 4 
# s = [5, 6] 
# m3 = 7 
# m4 = 8 
# key1 = 9 
# key2 = 10 
# b = #<Proc:[email protected](pry):77> 
# keys = {:key3=>11, key4=>12} 
+0

非常感謝Jorg。非常豐富 – AdamNYC 2013-05-02 05:29:32