【问题标题】:Issue with define_method in Ruby 3.0Ruby 3.0 中的 define_method 问题
【发布时间】:2021-04-28 19:05:24
【问题描述】:

我正在从 Ruby 2.7 升级到 3.0,但遇到了关键字参数更改的问题。

之前我们出于某些目的在代码中使用了 define_method。但是,随着关键字参数的变化,它不能再正确处理参数数组了。

class Foo
  def test(a: 1, b: 2)
    puts a
    puts b
  end

  old_method = instance_method(:test)

  define_method(:test) do |*args, &block|
    old_method.bind(self).call(*args, &block)
  end
end

Foo.new.test(a: 1)

这将引发 wrong number of arguments (given 1, expected 0) (ArgumentError)。它以前在 Ruby 2.7 中工作。我们可以做些什么来让 *args 再次工作?

【问题讨论】:

    标签: ruby ruby-3


    【解决方案1】:

    试试

      define_method(:test) do |*args, **kwords, &block|
        old_method.bind(self).call(*args, **kwords, &block)
      end
    

    Ruby 3.0 正在更改方法参数的处理,这会在 2.7 中给出弃用警告。有一些意外行为,包括 *args 数组中的关键字。这必须使用散列来完成,并且散列参数和关键字之间需要有更多的区别。因此,在 ruby​​ 3.x 中,您需要在双 splat 中捕获任意关键字集合,因为它们不能包含在 splat 参数中。

    我的理解大部分是不稳定的,但我将其作为一个明确的示例阅读,用于解释 ruby​​ 3.0 发行说明中的​​参数更改。

    【讨论】:

    • Official Explanation 向下滚动到“处理参数委托”
    • @MarlinPierce:我明白为什么您的解决方案是正确的。 OP 声称他的错误解决方案在 Ruby 2.7 之前就已经有效。你对此有什么解释吗?
    • @user1934428 好点。我很高兴我等着看它是否首先起作用。我的理解有点不稳定,但我想我记得这是更改文档中的一个明确示例。
    猜你喜欢
    • 2010-11-26
    • 1970-01-01
    • 2011-01-19
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    相关资源
    最近更新 更多