ruby - Ruby 中具有默认值的可选参数

标签 ruby named-parameters optional-arguments

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

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

end

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

my_function(b=100)

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

最佳答案

参数像这样绑定(bind)到参数:

  1. 只要参数列表开头有未绑定(bind)的强制参数,就从左到右绑定(bind)参数
  2. 只要参数列表末尾有未绑定(bind)的强制参数,就从右到左绑定(bind)参数
  3. 任何剩余的参数都从左到右绑定(bind)到可选参数
  4. 任何剩余的参数都被收集到一个数组中并绑定(bind)到 splat 参数
  5. 一个 block 被包装成一个Proc并绑定(bind)到 block 参数
  6. 如果有任何未绑定(bind)参数或剩余参数,引发一个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 步和示例中看到的那样,您不能这样做,因为可选参数是从左到右绑定(bind)的,但您想要指定中间参数。

请注意,这对 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 - Ruby 中具有默认值的可选参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16322706/

相关文章:

ruby - Ruby:脚本无法正确从YouTube抓取URL

Swift:为什么在这种情况下没有带标签的参数?

sql-server - 具有命名参数和计算的存储过程

c# - 通用方法和可选参数

java - Hbase 客户端 ConnectionLoss for/hbase 报错

ruby - ruby 中两次提交之间新行的代码覆盖率

ios - Calabash - 如何比较标签中给定 ID 的文本?

dart - 为了清楚起见,我想在 Dart 中使用命名参数。我应该如何处理它们?

python - 如何启用定义输入作为可选?

python - 如何创建带有可选参数的 Python 函数?