-1

I have written a code that has a decorator function in Ruby 2.7. It works well in that version but the same code does not work correctly in Ruby 2.6. If I remove the call for the the decorator i.e., wrapper_function then the code executes in Ruby 2.6 but it is not the functionality that I want. So what is my mistake here and how can I rectify it?

EDITED

#test.rb

FAMILYTREE = {
  "name": "Royal Family",
  "members": [
    [
      "King",
      "Male",
      "no mother"
    ],
    [
      "Queen",
      "Female",
      "no mother",
      "King"
    ]
    
  ]
}

module Wrapper
  def wrapper_function(func_name)
    new_name_for_old_function = "#{func_name}_old".to_sym
    alias_method(new_name_for_old_function, func_name)
    define_method(func_name) do |*args, **kwargs|
      begin
        result = send(new_name_for_old_function, *args, **kwargs)
        if result.instance_of?(Array) && result.any?
          result.map(&:name).join(' ')
        end
      end
    end
  end
end

class Person
  attr_accessor :name, :gender, :mother

  def initialize(name, gender, mother_name=nil)
    @name = name
    @gender = gender
    @mother = mother
  end

end

class Family
  extend Wrapper
  attr_accessor :family_name, :members

  def initialize(family_name)
    @family_name = family_name
    @members = []
  end

  def add_member(person_name, gender, mother_name, spouse_name)

    person = Person.new(person_name, gender, mother_name)

    members << person
  end
  wrapper_function(:add_member)
end


def create_family_tree(family_tree)
  #Initializing the family
  family_name = family_tree[:name]
  members = family_tree[:members]

  family = Family.new(family_name)
  members.each do |name, gender, mother_name, spouse_name|
    family.add_member(name, gender, mother_name, spouse_name)
  end
  family
end

fam = create_family_tree(FAMILYTREE)

The above is a complete file that shows the problem: To run it: ruby test.rb If the version is 2.7.1, then the code is executed without error. If it is 2.6.3, then I get this error: test.rb:54:in add_member: wrong number of arguments (given 5, expected 4) (ArgumentError)

In wrapper_function in lines 23 and 25 if I remove **kwargs then the program is executed and gives the desired result in version 2.6.3. So why is it happening like that?

Lax_Sam
  • 1,099
  • 2
  • 14
  • 32
  • Yes, and what does not work? – benjessop Aug 18 '20 at 06:48
  • Re "...but the same code does not work correctly in Ruby 2.6. " Please be specific. Does it raise an exception? If so, what is the exception and on what line is it raised? If it returns an incorrect value what is returned for what data? – Cary Swoveland Aug 18 '20 at 06:49
  • "does not work correctly" is not a precise enough error description for us to help you. *What* doesn't work? *How* doesn't it work? What trouble do you have with your code? Do you get an error message? What is the error message? Is the result you are getting not the result you are expecting? What result do you expect and why, what is the result you are getting and how do the two differ? Is the behavior you are observing not the desired behavior? What is the desired behavior and why, what is the observed behavior, and in what way do they differ? – Jörg W Mittag Aug 18 '20 at 06:52
  • Please make sure to construct a [mre]. Note that all three of those words are important: it should be an *example* only, you should not post your entire actual code, rather you should create a simplified example that demonstrates your problem. Also, it should be *minimal*, i.e. it should not contain anything that is not absolutely required to demonstrate the problem. (Most beginner problems can be demonstrated in less than 5 short simple lines of code.) And it should be *reproducible*, which means that if I copy&paste and run the code, I should see the exact same problem you see. – Jörg W Mittag Aug 18 '20 at 06:53
  • In your case, you posted 50 lines of code. I *suspect* that that is not "minimal" and that the vast majority of those lines can be removed. However, it is impossible for me to tell, because despite there already being too much code for us to read through, there is ironically also *not enough* code, because it depends on two other files that you didn't include, which makes the code "not reproducible". https://idownvotedbecau.se/itsnotworking/ https://idownvotedbecau.se/toomuchcode/ https://idownvotedbecau.se/nomcve/ – Jörg W Mittag Aug 18 '20 at 06:56
  • I have added a reproducible example. – Lax_Sam Aug 18 '20 at 08:00

1 Answers1

2

Yes - removing both of the **kwargs in wrapper_function will make it work in both 2.6.x and 2.7.x

It has to do with Ruby 2.7 deprecating automatic conversion from a hash to keyword arguments

Darren Hicks
  • 4,946
  • 1
  • 32
  • 35