Module: SubclassAware
- Defined in:
- lib/classy/subclass_aware.rb
Overview
SubclassAware allows a class to know about all of the subclasses that descend from it in the inheritance tree.
Example
class Parent
extend SubclassAware
end
class ChildA < Parent
end
class ChildB < Parent
end
Class ChildB1 < ChildB
end
Parent.subclasses # => [ ChildA, ChildB, ChildB1 ]
Note
SubclassAware sets and maintains the class variable @@classy_subclasses on the extending class, so in the unlikely event that this class variable is already in use, unusual bugs may result.
Warning
This module defines an inherited() class method on the extending class to keep track of subclasses. Unfortunately, if this method is later re-defined, this inherited() method is lost and subclass tracking will break. In order to work around this, constructions like the following might be necessary:
class ChildC < Parent
class << self; alias :old_inherited :inherited end
def self.inherited(sub)
old_inherited(sub)
# ...your inherited() code...
end
end
This is not considered an acceptable long-term state of affairs - hopefully in future versions of this module, this work around will not be necessary.
Class Method Summary collapse
-
.extended(klass) ⇒ Object
Instantiate a new Set of subclasses.
Instance Method Summary collapse
-
#forget_subclasses ⇒ Object
Clear all info about known subclasses.
-
#inherited(sub) ⇒ Object
Add the inheriting class to the list of subclasses.
-
#subclasses ⇒ Object
Return an array of all known subclasses (and sub-subclasses, etc) of this class.
Class Method Details
.extended(klass) ⇒ Object
Instantiate a new Set of subclasses. Not intended to be called directly.
53 54 55 |
# File 'lib/classy/subclass_aware.rb', line 53 def self.extended(klass) klass.class_exec { class_variable_set(:@@classy_subclasses, Set.new) } end |
Instance Method Details
#forget_subclasses ⇒ Object
Clear all info about known subclasses. This method is probably mainly useful for testing.
78 79 80 |
# File 'lib/classy/subclass_aware.rb', line 78 def forget_subclasses class_exec { class_variable_get(:@@classy_subclasses).clear } end |
#inherited(sub) ⇒ Object
Add the inheriting class to the list of subclasses. Not intended to be called directly.
TODO: Find a way for self.inherited on the extended class not to blow this away without requiring a bunch of alias chain hoops to be jumped through, as described above.
64 65 66 |
# File 'lib/classy/subclass_aware.rb', line 64 def inherited(sub) class_exec { class_variable_get(:@@classy_subclasses).add sub } end |
#subclasses ⇒ Object
Return an array of all known subclasses (and sub-subclasses, etc) of this class.
71 72 73 |
# File 'lib/classy/subclass_aware.rb', line 71 def subclasses class_exec { class_variable_get(:@@classy_subclasses).to_a } end |