From: Jeremy Kemper Date: 2008-09-24T07:46:16+09:00 Subject: [ruby-core:18824] Re: Feature idea: Class#subclasses On Tue, Sep 23, 2008 at 1:37 PM, Paul Brannan wrote: > On Wed, Sep 24, 2008 at 03:21:36AM +0900, Charles Oliver Nutter wrote: >> The move to discuss and possibly add this now is motivated by the ugly >> subclasses_of method in Rails, which uses ObjectSpace and >> singleton/metaclass tricks to speed up the search for a specific set of >> subclasses. The fast version of that logic does not work in JRuby >> without ObjectSpace enabled. > > I'm unclear why this couldn't be implemented using #inherited. It could, but at some penalty if you never need to use #subclasses. > One concern I have with Class#subclasses is that it could potentially > prevent anonymous subclasses from being garbage collected, if not > carefully implemented. This is a good reason to avoid #inherited. Same for a non-anonymous subclass that was remove_const. > I think the utility of this function is clear, though; it would be > useful for more than just Rails. Agreed! Here's a pure-Ruby implementation adapted from Rails: def subclasses subs = [] ObjectSpace.each_object(class << self; self; end) do |k| if k != self && (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id")) subs << k end end subs end The eval is needed to check whether the class is actually referenced by the constant with the same name. This omits subclasses that have been removed or replaced but not yet garbage collected. jeremy