Wir können Rubys Klassenhierarchie mit Bordmitteln erforschen:
Mit superclass erhalten wir die Basisklasse, von der
die aktuelle Klasse abgeleitet wurde.
Die Methode ancestors zeigt uns alle Oberklassen und
Module der angesprochenen Klasse, in der Reihenfolge, in der diese
nach Methoden durchsucht werden.
def lineage(cls)
puts "#{cls} -> #{cls.superclass}"
p cls.ancestors.collect { |m|
[m, m.class]
}
end
lineage String
# Ausgabe:
String -> Object
[[String, Class], [Enumerable, Module],
[Comparable, Module], [Object, Class],
[Kernel, Module]]
Der Ausgabe entnehmen wir, dass die Klasse String direkt von Object abstammt, aber die Module Enumerable und Comparable eingebunden hat. Die Klasse Object wiederum verwendet das Modul Kernel. Mehr Informationen zu Modulen gibt es in Kapitel 16.
Wenn wir das Modul ObjectSpace verwenden, können wir auch "`von oben"' kommen und zum Beispiel alle Unterklassen von Numeric ausfindig machen:
def subclasses(cls)
sub = []
ObjectSpace.each_object{ |obj|
if obj.class == Class and
obj.ancestors.member? cls
sub << [obj.ancestors.index(cls), obj]
end
}
sub.sort! { |a, b| a[0] <=> b[0] }
sub.each{ |i|
puts "#{i[1]} -> #{i[1].superclass}"
}
end
subclasses Numeric
# Ausgabe:
Numeric -> Object
Float -> Numeric
Integer -> Numeric
Fixnum -> Integer
Bignum -> Integer