Find all subclasses of a class/module

J

James Coglan

[Note: parts of this message were removed to make it a legal post.]

Hi list,

I'm trying to find all the classes/modules that descend from a particular
class/module. Please tell me there's a better way than this:

http://gist.github.com/6560
 
B

black eyes

the following are code in http://gist.github.com/6560

class Module
def subclasses
classes = []
ObjectSpace.each_object do |klass|
next unless Module === klass
classes << klass if self > klass
end
classes
end
end

I think the above code is good! but considering the class and module are
referenced by constants in ruby, use Module.constants is more naturally!
the following are mine!

the key is to get rid of the real constant such as PI and so on.

def find_children p_klass
Module.constants.find_all{|c_klass| c_klass!=c_klass.upcase ? p_klass
(Object.const_get c_klass) : nil}
end

# test!

class MyString < String
end

puts find_children( String) #=> MyString


require 'benchmark'
include Benchmark

puts find_children(Benchmark).include?(Tms) #=> fase
puts Tms.name #=> Benchmark::Tms
puts find_children(Benchmark).include?("Tms") #=> true
 
A

ara.t.howard

Hi list,

I'm trying to find all the classes/modules that descend from a
particular
class/module. Please tell me there's a better way than this:

http://gist.github.com/6560

just let ruby track it for you:

cfp:~ > cat a.rb
class A
end

class B < A
end

class C < A
end

class D < B
end

p D => D.subclasses
p C => C.subclasses
p B => B.subclasses
p A => A.subclasses
p Object => Object.subclasses



BEGIN {
class Class
def inherited other
super if defined? super
ensure
( @subclasses ||= [] ).push(other).uniq!
end

def subclasses
@subclasses ||= []
@subclasses.inject( [] ) do |list, subclass|
list.push(subclass, *subclass.subclasses)
end
end
end
}




cfp:~ > ruby a.rb
{D=>[]}
{C=>[]}
{B=>[D]}
{A=>[B, D, C]}
{Object=>[A, B, D, C]}


a @ http://codeforpeople.com/
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]
BEGIN {
class Class
def inherited other
super if defined? super
ensure
( @subclasses ||= [] ).push(other).uniq!
end

def subclasses
@subclasses ||= []
@subclasses.inject( [] ) do |list, subclass|
list.push(subclass, *subclass.subclasses)
end
end
end
}



That's probably more efficient than my version, but won't it fail to capture
relationships of any pre-existing classes? Seems it will only affect classes
defined after it has been loaded.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,173
Latest member
GeraldReund
Top