I am trying to upgrade gems from ruby 2.7.0 to 3.0.0. I have tried to read and plan ahead for what roadblocks I'd hit, like the Separation of positional and keyword arguments.
I have updated two gems smoothly, but I have started to upgrade a third and, while testing the 3.0 update with RSpec, have run into the following error:
ArgumentError:
wrong number of arguments (given 1, expected 0; required keyword: children)
I am trying it instantiate a Class through a Factory. The stack trace is pointing back to the arguments of this function:
# rubocop:disable Style/KeywordParametersOrder
def initialize(parent_obj: nil, children:, **attributes)
@attributes = attributes
@parent = parent_obj
@children_json = children
end
# rubocop:enable Style/KeywordParametersOrder
Though I don't think it is significant, I have included the rubocop dis/enable lines just in case they are important.
The Factory is calling the class in this fashion:
data = {:some_data=>"foo", :some_name=>"bar", :children=>[]}
Long::Class::Name.new(data)
Now, when I pry into the code between data and Long::Class::Name.new(data) and instantiate my own Long::Class::Name like below:
Long::Class::Name.new(children: children, attributes: data)
it results in a successful creation without the ArgumentError.
I think to myself, "Cool, I'll just update the Factory's Class call to this new format and re-run the tests." After doing this, I am still getting the same ArgumentError as above.
I believe this is an issue with positional/keyword arguments like I linked above, but I am having trouble seeing how I can correct this. Besides the link above, I have also looked into Ruby 3 Keyword Arguments, as well as Hash and Keyword Coercion and Ruby 3 Changes. I believe I am facing the "Unforeseen Consequences" portion of that last link.
I have also looked at this Stack Overflow issue about ArgumentError after updating from Ruby 2.7 to Ruby 3.0 and tried to understand how I could use the first portion of the first answer to help me with my issue (disregarding the Update related to a PR).
Any thoughts on how can I dispel or work around this error? I have many gems I need to update and I am sure this will not be the last time I see this error. Any help would be greatly appreciated. Let me know if more information is needed.
When you do this…
…you are calling the method with one positional argument (a hash containing the keys
:some_data
,:some_name
, and:children
) and no keyword argument.If you instead were to call it like this…
…you would be calling it with no positional argument and three keyword arguments.
This is called the "double splat" and was introduced for exactly your usecase, turning a hash into keyword arguments.