有没有一种很好的方法可以在 Ruby 中“重新打包”关键字参数?

Hul*_*iax 2 ruby keyword-argument

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

以下是正常的。

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
Run Code Online (Sandbox Code Playgroud)

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

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

我知道你可以解析method(__method__).parameters,做一些体操,并将所有东西打包成一个哈希,可以被双重分割并传递给bar. 我只是想知道核心中是否已经有一些东西以一种很好的、​​整洁的方式做到了这一点?

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

Sch*_*ern 7

是的,**args将收集任意关键字参数作为哈希。再次使用 ** 将 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
Run Code Online (Sandbox Code Playgroud)

如果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
Run Code Online (Sandbox Code Playgroud)