Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
497 views
in Technique[技术] by (71.8m points)

ArgumentError when upgrading from Ruby 2.7 to 3.0 - related to separation of positional and keyword arguments?

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.

question from:https://stackoverflow.com/questions/65912322/argumenterror-when-upgrading-from-ruby-2-7-to-3-0-related-to-separation-of-pos

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When you do this…

data = {:some_data=>"foo", :some_name=>"bar", :children=>[]}
Long::Class::Name.new(data)

…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…

Long::Class::Name.new(**data)

…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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

Just Browsing Browsing

[6] html - How to create even cell spacing within a

2.1m questions

2.1m answers

60 comments

57.0k users

...