繁体   English   中英

Ruby中的默认值的可选参数

[英]Optional arguments with default value in Ruby

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

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

end

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

my_function(b=100)

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

参数绑定到这样的参数:

  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 = #<Proc:0x007fdc732cb468@(pry):42>

因此,正如您可以从上面的步骤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 = #<Proc:0x007fdc75135a48@(pry):77>
# keys = {:key3=>11, key4=>12}

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

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

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

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

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

my_function(b: 100)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM