Continuing on with my previous post, I have found it useful sometimes to be able to programmatically discover all the classes that inherit from a specific class. I have used this as a light form of Inversion of Control where I autodiscover all the objects that implement a specific interface. Its particularly useful if you don’t care what order you then call each object: for instance running a bunch of diagnostic tests on a system (and it doesn’t matter the order the tests are run in), or loading up a bunch of filters for log lines that can be tested against a line in any order.
This is easily done in Ruby with the ObjectSpace class, the example below would find every class that inherits from a class named
Job, then instantiate an object from it and add it to an array:
1 2 3 4 5 6 7
A Note on Namespaces
If the classes you are working with are inside modules, when using modules as namespaces in Ruby, you would indeed need to look for them via the
Module::Class syntax (which is obvious, or else what good would the namespace do you, but I felt the need to mention it here since Python also has some particulars when it comes to namespacing).
A Note on Later Generations
This example would not find generations beyond the first. You could fairly easily adapt a recursive form of it that would. For my example use cases above, that is just not important.
I am using the following form in Python, but I am not 100% sure yet this is what everyone would agree is the preferred form. I gather that some built-in methods like
__subclasses__ are sometimes not preferred over other forms added to the language later.
Anyway, this works, basically the same example as above:
1 2 3 4
However, depending on if you are doing this inside a module or outside of a module, you might want a different global function than
globals(). There are a few options that look like they differ based on your current scope and intent.
Dart has a complete reflection API in
dart:mirrors, and after a little reading about it (and some help from stack overflow of course, though looks like a few parts of this answer are now changed in Dart), I was able to piece together the code below. Note this example is a bit more complete (it shows the class declarations) because I wanted something you could actually run in the dart interpreter (again, with no cli REPL, its a little harder to just try things out).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
There was quite a bit I was not familiar with myself here. One was working with dart’s
Symbol class, which is familiar from Ruby but unfortunately is implemented as a class rather than a type so you need some extra syntax to work with them. Also, that
newIntance returns an
ObjectMirror not the object itself (though that is solved with the
This example will look in the root library, as above in both Ruby and Python, if you intend to search only a specific library it would take some modification to do so.