I'm working on an upgrade from Ruby 2.7 to 3.0 and faced an issue with the keyword arguments change.
Previously we used define_method in our code for some purposes. However, with the keyword arguments change, it can no longer handle an array of arguments properly anymore.
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)
This will raise wrong number of arguments (given 1, expected 0) (ArgumentError)
. And it previously worked in Ruby 2.7. Is there anything we can do to get the *args to work again?
Try
Ruby
3.0
is changing the handling of method arguments which give a deprecation warning in2.7
. There is some unexpected behavior including a keywords in a*args
array. This had to be done using a hash and there needs to be more of a distinction between a hash argument and keywords. So in ruby3.x
you need to capture an arbitrary collection of keywords in a double splat because they cannot be included in the splat argument.Mostly my understanding is shaky but I read this as an explicit example in the explanation of the changed to the arguments in the release notes for ruby
3.0
.