Forum: Ruby Is there a way to know what are the subclasses of a given class ?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
0df4a6c75caf1bd9b01d2dcbfb085ee4?d=identicon&s=25 Sandro Paganotti (Guest)
on 2008-11-19 10:12
(Received via mailing list)
Hello

Do you know if there's a trick to retrieve a list of all the subclasses
of a
given class ?

class A
  class B
  end
  class C
  end
end

like  A.subclasses  --> [B,C] ?

Thanks
Sandro
0df4a6c75caf1bd9b01d2dcbfb085ee4?d=identicon&s=25 Sandro Paganotti (Guest)
on 2008-11-19 10:15
(Received via mailing list)
[SOLVED]

I just find out that you can call:

A.constants --> ["B","C"]

Thank you

Sandro

On Wed, Nov 19, 2008 at 10:10 AM, Sandro Paganotti <
F50f5d582d76f98686da34917531fe56?d=identicon&s=25 Peter Szinek (Guest)
on 2008-11-19 10:53
(Received via mailing list)
In your above example, B is not subclass of A (B is not even defined,
just A::B).

Also, how about

class A
  class B
  end
  class C
  end
D = E = F = 5
end

 >> A.constants
=> ["C", "B", "D", "F", "E"]

What are you trying to do exactly? Maybe modules would be better?

Cheers,
Peter
___
http://www.rubyrailways.com
http://scrubyt.org
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2008-11-19 10:58
Sandro Paganotti wrote:
> Do you know if there's a trick to retrieve a list of all the subclasses
> of a
> given class ?

Only this that I know of:

class A; end
class B<A; end

require 'enumerator'
p ObjectSpace.to_enum(:each_object, Class).
  select { |c| c.superclass == A }
0df4a6c75caf1bd9b01d2dcbfb085ee4?d=identicon&s=25 Sandro Paganotti (Guest)
on 2008-11-19 11:04
(Received via mailing list)
Thanks Peter :D

That exactly what I was lloking for :)
E088bb5c80fd3c4fd02c2020cdacbaf0?d=identicon&s=25 Jesús Gabriel y Galán (Guest)
on 2008-11-19 11:17
(Received via mailing list)
>> Sandro
>>> class A
>>>  class B
>>>  end
>>>  class C
>>>  end
>>> end
>>>
>>> like  A.subclasses  --> [B,C] ?

As has been mentioned, in your example B and C are not subclasses of A.
If you want to list all subclasses of a class you can do this:

irb(main):001:0> class A
irb(main):002:1> class << self
irb(main):003:2> attr_accessor :subclasses
irb(main):004:2> end
irb(main):005:1> def self.inherited child
irb(main):006:2> (A.subclasses ||= []) << child
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):009:0> A.subclasses
=> nil
irb(main):010:0> class B < A; end;
irb(main):011:0* A.subclasses
=> [B]
irb(main):012:0> class C < B; end;
irb(main):013:0* A.subclasses
=> [B, C]
irb(main):014:0> class D < A; end;
irb(main):015:0* A.subclasses
=> [B, C, D]

Hope this helps,

Jesus.
86e33dee4a89a8879a26487051c216a8?d=identicon&s=25 Michael Fellinger (Guest)
on 2008-11-19 11:40
(Received via mailing list)
On Wed, Nov 19, 2008 at 7:12 PM, Jesús Gabriel y Galán
<jgabrielygalan@gmail.com> wrote:
>>> Sandro
>>>> class A
>
> => nil
> Hope this helps,
>
> Jesus.
>
>

Little different style maybe:

class A
  @subclasses = []
  def self.inherited(into) @subclasses << into end
  def self.subclasses() @subclasses end
end
# nil
class B < A
end
# nil
A.subclasses
# [B]

And a slower and hacky alternative:

require 'set'; found = Set.new; ObjectSpace.each_object(Class){|o|
found << o if o < A }
# 446
found
# #<Set: {B}>

^ manveru
E088bb5c80fd3c4fd02c2020cdacbaf0?d=identicon&s=25 Jesús Gabriel y Galán (Guest)
on 2008-11-19 11:55
(Received via mailing list)
On Wed, Nov 19, 2008 at 11:36 AM, Michael Fellinger
<m.fellinger@gmail.com> wrote:
> On Wed, Nov 19, 2008 at 7:12 PM, Jesús Gabriel y Galán
> <jgabrielygalan@gmail.com> wrote:

> Little different style maybe:
>
> class A
>  @subclasses = []
>  def self.inherited(into) @subclasses << into end
>  def self.subclasses() @subclasses end
> end

Yep, much cleaner :-).
I made a mess while I was typing in irb about closing the << self early,
and forgetting to initialize the array, so that was the result. I
probably wanted to type this:

irb(main):001:0> class A
irb(main):002:1> class << self
irb(main):003:2> attr_reader :subclasses
irb(main):004:2> def inherited(child)
irb(main):005:3> subclasses << child
irb(main):006:3> end
irb(main):007:2> end
irb(main):008:1> @subclasses = []
irb(main):009:1> end

but anyway your version is cleaner...

Jesus.
This topic is locked and can not be replied to.