【问题标题】:Is there a nice way to "repackage" keyword args in Ruby?有没有一种在 Ruby 中“重新打包”关键字参数的好方法?
【发布时间】:2021-03-11 19:15:39
【问题描述】:

我有几个方法接受许多(关键字)参数,最终将同一组参数传递给另一个方法。

以下是正常的。

def foo(a:, b:, c:, d:, e:)
  bar('var', a:a, b:b, c:c, d:d, e:e)
end

# takes the same arguments as #foo + one more
def bar(var, a:, b:, c:, d:, e:)
  ...
end

这有点乏味和烦人。我想知道 Ruby 核心中是否有任何东西可以轻松执行以下操作...

def foo(a:, b:, c:, d:, e:)
  bar('var', <something that automagically collects all of the keyword args>)
end

我知道您可以解析 method(__method__).parameters,做一些体操,然后将所有内容打包成一个哈希,然后可以双拼并传递给 bar。我只是想知道核心中是否已经有一些东西可以以一种很好、简洁的方式做到这一点?

如果有一些东西以更一般的方式应用,即不仅适用于关键字 args,那么这当然也很有趣。

【问题讨论】:

    标签: ruby keyword-argument


    【解决方案1】:

    是的,**args will gather arbitrary keyword arguments 作为哈希。再次使用 ** 将 Hash 扁平化为 bar 的关键字参数,Ruby 3 将不再为您执行此操作。

    def foo(**bar_args)
      # The ** is necessary in Ruby 3.
      bar('var', **bar_args)
    end
    
    def bar(var, a:, b:, c:, d:, e:)
      puts "#{var} #{a} #{b} #{c} #{d} #{e}"
    end
    

    如果foo 从不使用这些参数,这是合适的,它只是将它们传递给bar。如果foo 要使用某些参数,则应在foo 中定义这些参数。

    def foo(a:, **bar_args)
      puts "#{a} is for a"
      bar('var', a: a, **bar_args)
    end
    
    def bar(var, a:, b:, c:, d:, e:)
      puts "#{var} #{a} #{b} #{c} #{d} #{e}"
    end
    

    【讨论】:

    • 是的,这就是关键……从来没有在foo 中使用bar_args。我已经翻过一些恶心的东西并试图清理它。我遇到过foo 使用bar_args 内部传递的值的情况。我认为那是臭代码,适合进行一些重构......
    猜你喜欢
    • 2016-06-20
    • 2011-01-28
    • 2011-08-29
    • 2022-12-02
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 2023-02-05
    • 2014-02-10
    相关资源
    最近更新 更多