如下面的代码所示,在超类中定义类访问器可能会产生意外行为,因为类访问器对于所有子类都是相同的变量。
class Super
cattr_accessor :name
end
class SubA < Super; end
class SubB < Super; end
SubA.name = "A"
SubB.name = "B"
SubA.name
=> "B" # unexpected!
我希望每个子类都有一个独立的类访问器,因此可能的解决方案是将cattr_accessor从超类中移出并将其放在每个子类中。
class Super; end
class SubA < Super
cattr_accessor :name
end
class SubB < Super
cattr_accessor :name
end
SubA.name = "A"
SubB.name = "B"
SubA.name
=> "A" # expected!
这个解决方案是一个好习惯吗?你知道更好的选择吗?
答案 0 :(得分:6)
打开Super
的单身人士课程并定期attr_accessor
:
class Super
class << self
attr_accessor :name
end
end
这应该为您提供所需的语义:“类级实例变量”。
但是,我会注意:name
Super
上Super
的任何值都不会被attr_accessor
的孩子继承。如果你仔细想想,这是有道理的:孩子们继承{{1}},而不是属性本身。
有一些解决方法,最明显的是rails提供class_attribute
,它提供了孩子继承父属性值的能力,除非明确覆盖。