传递Ruby 2关键字参数而不明确指定它们

时间:2015-05-28 00:39:39

标签: ruby ruby-on-rails-4

如何在不指定每个方法的情况下将关键字参数传递给我的代码中的另一个方法。

考虑以下方法,为kwargs提供新的第一类支持:

def foo(obj, bar: 'a', baz: 'b')
  another_method(bar, baz)
end

考虑旧的Ruby选项哈希语法:

def foo(obj, options = {})
  another_method(options)
end

我想传递关键字参数,而不是显式地指定每个参数,就像旧选项哈希语法的情况一样。这甚至可能吗?

2 个答案:

答案 0 :(得分:2)

您可以使用double-splat运算符:

def a(q: '1', w: '2')
  p q
  p w
end

def b(**options)
  a(options)
end

b
# => 1
# => 2

b(q: '3', w: '4')
# => 3
# => 4

答案 1 :(得分:0)

关键字参数的工作方式类似于旧的Ruby选项哈希语法"。哈希的键将替换为关键字及其值作为参数。这应该可以正常工作:

def foo(obj, bar: 'a', baz: 'b')
  another_method(bar, baz)
end

arg_hash = { bar: 'alt bar', baz: 'alt baz' }

foo(Object.new, arg_hash)

要注意的一些事情

如果您的哈希键是字符串,例如{ 'bar' => 'alt bar', 'baz' => 'alt baz' },那么这不会起作用。您将收到ArgumentError: wrong number of arguments (2 for 1)错误。这很容易通过在哈希上调用.symbolize_keys来修复Rails。如果您不在Rails中,则必须手动转换密钥或重新实现该方法。

此外,在Rails中,HashWithIndifferentAccess(例如控制器中的params哈希)虽然它有键的字符串和符号,但是不能以这种方式使用。如果您通过params,它会查看字符串键,您将得到与上述相同的错误。我不确定为什么会出现这种情况,但我的猜测是因为params hash以字符串开头并添加了符号,因此符号是次要的而不是默认符号。尽管如此总猜。