Проблема с define_method в Ruby 3.0

Я работаю над обновлением 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 снова заработал?

1 ответ

Пытаться

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

Ruby меняет обработку аргументов метода, которые выдают предупреждение об устаревании в 2.7. Произошло непредвиденное поведение, включая ключевые слова в *argsмножество. Это должно было быть сделано с использованием хеша, и должно быть больше различий между хеш-аргументом и ключевыми словами. Так в рубине 3.x вам нужно записать произвольную коллекцию ключевых слов в двойной знак, потому что они не могут быть включены в аргумент splat.

В основном мое понимание шаткое, но я читаю это как явный пример в объяснении измененных аргументов в примечаниях к выпуску для ruby 3.0.

Другие вопросы по тегам