Ruby中的默认值的可选参数

我想创建一个具有默认值的可选参数的函数

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

并使用我想要指定的参数调用该函数

 my_function(b=100) 

我如何在Ruby 1.9.2中实现这一目标?

你不能在Ruby <2.0中那样做(或类似的东西)。 你能做的最好的事情是:

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

参数绑定到这样的参数:

  1. 只要参数列表的开头有未绑定的必需参数,就从左到右绑定参数
  2. 只要参数列表末尾有未绑定的必需参数,就可以从右到左绑定参数
  3. 任何剩余的参数都从左到右绑定到可选参数
  4. 任何剩余的参数都被收集到一个数组中并绑定到splat参数
  5. 块被包装到Proc并绑定到块参数
  6. 如果有任何未绑定参数或剩余参数,则raise ArgumentError

这是一个例子:

 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 = # 

因此,正如您可以从上面的步骤3和示例中看到的那样,您无法执行此操作,因为可选参数是从左到右绑定的,但您要指定中间参数。

请注意,这会对API设计产生影响:您应该设计参数列表,使得最“不稳定”的可选参数(即用户最可能想要提供的参数)位于左侧最远的位置。

Ruby 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 = # # keys = {:key3=>11, key4=>12} 

所以你试图实现关键字参数? 这应该是Ruby 2.0中的一个新function,但您可以尝试使用参数哈希在1.9.x中模拟它。 这是一篇讨论如何实现这一目标的post ,它提供了以下代码示例:

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