2013-05-01 166 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