rubydynamic-method

Ruby create methods from a hash


I have the following code I am using to turn a hash collection into methods on my classes (somewhat like active record). The problem I am having is that my setter is not working. I am still quite new to Ruby and believe I've gotten myself turned around a bit.

class TheClass
  def initialize
    @properties = {"my hash"}
    self.extend @properties.to_methods
  end
end

class Hash
  def to_methods
    hash = self
    Module.new do
      hash.each_pair do |key, value|
        define_method key do
          value
        end
        define_method("#{key}=") do |val|
          instance_variable_set("@#{key}", val)
        end
      end
    end
  end
end

The methods are created and I can read them on my class but setting them does not work.

myClass = TheClass.new
item = myClass.property # will work.
myClass.property = item # this is what is currently not working.

Solution

  • Your getter method always returns the value in the original hash. Setting the instance variable won't change that; you need to make the getter refer to the instance variable. Something like:

    hash.each_pair do |key, value|
      define_method key do
        instance_variable_get("@#{key}")
      end
      # ... define the setter as before
    end
    

    And you also need to set the instance variables at the start, say by putting

    @properties.each_pair do |key,val|
      instance_variable_set("@#{key}",val)
    end
    

    in the initialize method.

    Note: I do not guarantee that this is the best way to do it; I am not a Ruby expert. But it does work.