> Say I've got a class and I know it has subclasses. I'm absolutely sure
> there must be an irb ObjectSpace one-liner to give me all the
> subclasses of an arbitrary class.
Yup 
> I've been able to find the Class instance method #inherited(), which
> takes another class and tells you yay or nay, but a simple one-liner
> to return a class's subclasses has so far proved out of my reach.
ObjectSpace.each_object( Class ) {|klass| puts klass if klass < IO }
...will give you any class that is a subclass of IO. Could pretty
easily be wrapped into a method you could call on a class. In fact:
class Class
def subclasses
out =
ObjectSpace.each_object( Class ) {|k| out << k if k < self }
return out
end
end
Stick that in your .irbrc and call IO.subclasses. YEAH.
> I know it exists. I just don't know what it is. I'm also kind of
> stymied because it appears ObjectSpace has #each_object but not #each.
> That seems so weird to me.
What would #each do that #each_object doesn't?
Ben
#each enables #collect, doesn't it? It's the core iterator for all
those other iterator methods.
I wanted to throw the horns all metal-style when I first saw this, but
it doesn't work in irb:
class Class
def subclasses
out =
ObjectSpace.each_object( Class ) {|k| out << k if k < self }
return out
end
end
=> nil
Event.subclasses
NoMethodError: protected method `subclasses' called for Event:Class
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/base.rb:1236:in
`method_missing'
from (irb):9
Event.new.subclasses
NoMethodError: undefined method `subclasses' for #<Event:0x3556b50>
from /opt/local/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/base.rb:1861:in
`method_missing'
from (irb):10
I thought maybe I needed to use Class.class_eval instead:
Class.class_eval do
def subclasses
out =
ObjectSpace.each_object( Class ) {|k| out << k if k < self }
return out
end
end
but I got identical error output when I tried that. In fact I think I
just used a synonym for "class Class" by using "Class.class_eval" and
the whole thing was very cargo cult of me.
Anyway, that < operator for inheritance is insanely cool, but I'm
missing something getting this to work.
Couldn't get Pat's solution to work either!
ObjectSpace.each_object {|o| puts o.name if o.is_a?(Class) && o < Event}
=> 55128
Maybe just molasses in the brainpan today.
···
On 3/5/07, Ben Bleything <ben@bleything.net> wrote:
On Tue, Mar 06, 2007, Giles Bowkett wrote:
--
Giles Bowkett
http://www.gilesgoatboy.org
http://giles.tumblr.com/