我试图扩展 code from this question用于保存属性值的记录。但是,如果有多个属性,我的代码就会失败。这是代码:
class Class
def attr_accessor_with_history(attr_name)
attr_name = attr_name.to_s
attr_reader attr_name
ah=attr_name+"_history"
attr_reader ah
class_eval %Q{
def #{attr_name}= (attr_name)
@attr_name=attr_name
if @ah == nil
@ah=[nil]
end
@ah.push(attr_name)
end
def #{ah}
@ah
end
def #{attr_name}
@attr_name
end
}
end
end
这里是一个用于测试的虚拟类
class Foo
attr_accessor_with_history :bar
attr_accessor_with_history :bar1
end
f = Foo.new
f.bar = 1
f.bar = 2
f.bar1 = 5
p f.bar_history
p f.bar1_history
由于某些原因,f.bar
和 f.bar1
都返回 5
和 f.bar_history = f.bar1_history = [无,1、2、5]
。知道这是为什么吗?
您使用的是 @ah
和 @attr_name
而不是 @#{ah}
和 @#{attr_name}
在方法中获取/设置时。这意味着它们总是设置和返回相同的实例变量,而不是不同的、动态命名的实例变量。
class Class
def attr_accessor_with_history(attr_name)
class_eval %{
attr_reader :#{attr_name}, :#{attr_name}_history
def #{attr_name}=(value)
@#{attr_name} = value
@#{attr_name}_history ||= [nil]
@#{attr_name}_history << value
end
}
end
end
我通常还略微清理了您的代码,使其(我认为)更清晰、更简洁。
我是一名优秀的程序员,十分优秀!