【问题标题】:Pass Ruby 2 keyword arguments without specifying them explicitly传递 Ruby 2 关键字参数而不明确指定它们
【发布时间】:2015-08-10 07:13:51
【问题描述】:

如何在我的代码中将关键字参数传递给对另一个方法的调用,而无需指定每个方法。

考虑使用对 kwargs 的新的一流支持的以下方法:

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

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

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

我想传递关键字参数,而不像旧选项哈希语法那样明确指定每个参数。这可能吗?

【问题讨论】:

    标签: ruby ruby-on-rails-4


    【解决方案1】:

    您可以使用双 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
    

    【讨论】:

    • 这能回答 OP 吗?我想用参数调用另一个方法而不在原始方法中明确指定它们,而不是创建另一个接受任何参数的方法。
    • 为什么不呢?该方法不接受任何参数。在我的例子中,如果你尝试b(x: '1'),你会得到unknown keyword: x
    • 感谢您指出双 splat 运算符的存在。我在其他任何地方都找不到有关如何执行此操作的信息。
    【解决方案2】:

    关键字参数的工作方式类似于您的“旧 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) 错误。这很容易在 Rails 中通过在哈希上调用 .symbolize_keys 来修复。如果您不在 Rails 中,则必须手动转换键或重新实现该方法。

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

    【讨论】:

      猜你喜欢
      • 2020-03-25
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      • 2020-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-14
      相关资源
      最近更新 更多