Ответ Чака лучше, чем мои последние две попытки. Собственный класс не self.class
, как я думал; это потребовало лучшего теста, чем я написал, чтобы понять это.
Используя мой старый код, я протестировал следующим образом и обнаружил, что классом действительно манипулировали, а не экземпляром:
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}" }
Вывод был:
Common methods between a & b:
my_other_attr=
my_attr
my_attr=
my_other_attr
Это явно опровергает мою предпосылку. Мои извинения, Чак, ты был прямо все время.
Предыдущий ответ:
attr_accessor
работает только при оценке в определении класса, но не при инициализации экземпляра. Поэтому единственный способ сделать то, что вы хотите, - это использовать instance_eval
со строкой:
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
Чтобы проверить это, попробуйте:
c = MyClass.new :my_var => 1
puts c.my_var