Ruby 方法和多个默认值的排序

标签 ruby

我似乎无法做到这一点(我以前可以用 Python 做到这一点)。让我解释一下..

假设我在 Ruby 中有以下方法:

def someMethod(arg1=1,arg2=2,arg3=3)
...
...
...
end

现在我可以调用这个方法

someMethod(2,3,4)
someMethod(2,3)
someMethod(2)

并且参数是按照它们各自的顺序获取的。但是如果我想在我的编程中的某个时刻给出 arg2 并且想要 arg1 和 arg3 的默认值怎么办?

我尝试编写 someMethod(arg2=4) 但这在 Ruby 1.9 中似乎不起作用。它所做的是它仍然认为 arg1 是 4。在 python 中我至少可以摆脱这个,但在 ruby​​ 中我不确定。有没有人有什么优雅的想法?

最佳答案

目前唯一优雅的解决方案是使用哈希作为参数列表:

def some_method(options = {})
  defaults = {:arg1 => 1, :arg2 => 2, :arg3 => 3}
  options = defaults.merge(options)
  ...
end

以及稍后在代码中调用您的方法时使用隐式散列:

some_method()
some_method(:arg1 => 2, :arg2 => 3, :arg3 => 4)
some_method(:arg2 => 4)

在 Ruby 1.9 中,您可以使用新的散列键语法来获得更像 Python 中的 ir:

some_method(arg1: 2, arg2: 3, arg3: 4)

如果你想要更简单的语法并且仍然能够使用位置参数,那么我建议使用这样的东西:

def some_method(*args)
  defaults = {:arg1 => 1, :arg2 => 2, :arg3 => 3}
  options = args.last.is_a?(::Hash) ? args.pop : {}
  options = defaults.merge(options)

  arg1 = args[0] || options[:arg1]
  arg2 = args[1] || options[:arg2]
  arg3 = args[2] || options[:arg3]
  ...
end

some_method()
some_method(2)
some_method(3,4,5)
some_method(arg2: 5)
some_method(2, arg3: 10)

如果你想模仿 Ruby 参数数字检查方法,你可以添加:

fail "Unknown parameter name(s) " + (options.keys - defaults.keys).join(", ") + "." unless options.length == defaults.length

编辑:
我用 Jonas Elfström 更新了我的答案的评论

关于Ruby 方法和多个默认值的排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2371044/

相关文章:

ruby-on-rails - 具有动态哈希的 Rails update_attributes

ruby - 有没有办法访问 block 外 block 内定义的局部变量?

ruby - 使用函数填充 Ruby 哈希

Netbeans 中的 Ruby Watir 和 Cucumber - 场景未定义

ruby - 帮助 ruby​​ 脚本,(如果行包含,忽略)

ruby-on-rails - 为 ActiveRecord 关联扩展编写规范

ruby - 有没有更好的方法在 Ruby 中添加 if not nil?

ruby - Ruby Sinatra ActiveRecord 中的基本搜索

ruby - 如何解决在 Cygwin 中找不到 -lcrypt?

ruby-on-rails - ruby on rails教程第3.2节rspec测试报错