鉴于下面代码中的超类,我希望所有子类都有一些实例变量。
下面的代码做到了这一点,但未能为所有可能的子类正确初始化该变量。
我打开了我的超类的特征类。这是代码(也在rubyfiddle中):
class SomeSuperClass
class << self
attr_accessor :variable
@variable = ': )' # This does't seem to have any effect
end
self.variable = 'This only works for the superclass'
end
class SubClass < SomeSuperClass; end
puts SomeSuperClass.variable # => 'This only works for the superclass'
puts SubClass.variable # => ''
SomeSuperClass.variable = 'I am the superclass'
SubClass.variable = 'I am the subclass'
puts SomeSuperClass.variable # => 'I am the superclass'
puts SubClass.variable # => 'I am the subclass'
我想初始化所有可能的子类。在前两个 put 上,onlySomeSuperClass.variable
被初始化。我不知道如何为所有可能的子类初始化这个变量。有任何想法吗?
我发现的最佳解决方案是延迟初始化变量,覆盖访问器,如下所示:
class SomeSuperClass
def self.variable
@variable ||= 'Hi'
end
end
动机:
我需要给定类的所有子类,我们称之为 Vigilant,能够监视其直接子类上发生的一些事情。此信息存储在类中,因此每个类都有不同的状态。
我不能使用类变量,因为两个类 A < B 将修改同一个变量。我也不能直接访问子类,所以我需要一种方法来为 Vigilant 的所有子类提供存储和检索有关其子类的信息的能力。
通过定义打开 eigen 类的访问器,可以说:
A.singleton_class.instance_eval { attr_accessor :x }
现在所有子类 Bclass B < A; end
都可以这样做B.x
,因为方法(访问器)已添加到其超类 eigen 类中,因此可以在查找中找到。
第一个例子表明 Bx 与 Ax 不同
现在,我真的不明白 x 在哪里;变量,而不是访问器。如果我这样做,B.instance_variables
则[]
与 B.singleton_class.instance_variables 相同