rubyruby-2.6ruby-2.7

Code works well in Ruby 2.7 but not in Ruby 2.6.3


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?


Solution

  • 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