Chuck 的回答比我最近两次尝试的要好。特征类不像我想的那样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
这显然反驳了我的假设。我很抱歉 Chuck,你一直都是对的。
旧答案:
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