Given the superclass in the code below, I want all subclasses to have some instance variable.
The code below does that, but fails to properly initialize that variable for all possible subclasses.
I opened the eigenclass of my superclass. Here is the code (also in 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'
I would like to have all possible sublcasses initialized. On the first two puts, only SomeSuperClass.variable
is initialized. I don't know how to initialize this variable for all possible subclasses. Any ideas?
The best solution I found is to lazy-initialize the variable, overriding the accessor, as in:
class SomeSuperClass
def self.variable
@variable ||= 'Hi'
end
end
The motivation:
I need all subclasses of a given class, lets call it Vigilant, be able to monitor some things happening on their direct subclasses. This information is stored on the class, and therefore have a different state for each one.
I can't use a class variable, since two classes A < B would be modifying the same variable. I can't access directly to the subclasses either, so I needed a way to give all subclasses of Vigilant the capacity for storing and retrieving the information about their subclasses.
By defining the accessors opening the eigen class, lets say:
A.singleton_class.instance_eval { attr_accessor :x }
All subclasses Bclass B < A; end
are now able to do B.x
, because a method (an accessor) was added to its superclass eigen class, and therefore can be found on the lookup.
And the first example shows that B.x is different from A.x
Now, what I'm really not understanding is where x is; the variable, not the accessors.
If I do B.instance_variables
it shows []
, same with B.singleton_class.instance_variables