Declaring instance variables iterating over a hash!

前端 未结 4 1429
忘掉有多难
忘掉有多难 2021-02-02 16:43

i want to do the following:

I want to declare the instance variables of a class iterating over a dictionary.

Let\'s assume that i have this hash

         


        
4条回答
  •  离开以前
    2021-02-02 17:07

    Chuck's answer is better than my last two attempts. The eigenclass is not self.class like I had thought; it took a better test than I had written to realize this.

    Using my old code, I tested in the following manner and found that the class was indeed manipulated and not the instance:

    a = MyClass.new :my_attr => 3
    b = MyClass.new :my_other_attr => 4
    
    puts "Common methods between a & b:"
    c = (a.public_methods | b.public_methods).select { |v| a.respond_to?(v) && b.respond_to?(v) && !Object.respond_to?(v) }
    c.each { |v| puts "    #{v}" }
    

    The output was:

    Common methods between a & b:
        my_other_attr=
        my_attr
        my_attr=
        my_other_attr
    

    This clearly disproves my presupposition. My apologies Chuck, you were right all along.

    Older answer:

    attr_accessor only works when evaluated in a class definition, not the initialization of an instance. Therefore, the only method to directly do what you want is to use instance_eval with a string:

    class MyClass
      def initialize(params)
        #hash = {"key1" => "value1","key2" => "value2","key3" => "value3"}
        params.each do |k,v|
          instance_variable_set("@#{k}", v)
          instance_eval %{
            def #{k}
              instance_variable_get("@#{k}")
            end
            def #{k}= (new_val)
              instance_variable_set("@#{k}", new_val)
            end
          }
        end
      end
    end
    

    To test this try:

    c = MyClass.new :my_var => 1
    puts c.my_var
    

提交回复
热议问题