# Automatic instantiation of subclasses

**URL:** <https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857>\
**Category:** Ruby\
**Created:** [August 8, 2006, 11:19am UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857 "2006-08-08T11:19:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![kilivor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@kilivor](https://www.ruby-forum.com/u/kilivor)\
**Post date:** [August 8, 2006, 11:19am UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857/1 "2006-08-08T11:19:09Z")

</div>

Hi!

First sorry I am a beginner ;-( What I want to do is: automatically  
instantiate subclasses of a given class, say, A.

class A  
end

class A1 \< A  
end

class A2 \<A  
end

So I want to know the names of A subclasses: A1 and A2. Then instantiate  
via reflection. Is it possible?

Using ObjectSpace it is possible to know all the instantiated objects of  
a class. But here no objects yet.

Thanks a lot.

---

<div class="post-metadata">

**Author:** ![kilivor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@kilivor](https://www.ruby-forum.com/u/kilivor)\
**Post date:** [August 8, 2006, 11:35am UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857/2 "2006-08-08T11:35:17Z")

</div>

On Tue, Aug 08, 2006 at 06:19:12PM +0900, Kilivor K. wrote:

> end
> 
> So I want to know the names of A subclasses: A1 and A2. Then instantiate  
> via reflection. Is it possible?

class A  
class \<\< self; attr\_reader :subclasses end  
def self.inherited(x); (@subclasses ||= []) \<\< x end  
end

class A1 \< A; end  
class A2 \< A; end

A.subclasses # =\> [A1, A2]  
A.subclasses.map{|x| x.new} # =\> [#A1:0xa7d73064, #A2:0xa7d73050]

class A1b \< A1; end  
A1.subclasses # =\> [A1b]

You can use @@subclasses if you want A.subclasses to include A1b:

class A  
@@subclasses = []  
def self.subclasses; @@subclasses end  
def self.inherited(x); @@subclasses \<\< x end  
end

class A1 \< A; end  
class A2 \< A; end

A.subclasses # =\> [A1, A2]  
A.subclasses.map{|x| x.new} # =\> [#A1:0xa7d3c03c, #A2:0xa7d3c028]

class A1b \< A1; end  
A.subclasses # =\> [A1, A2, A1b]

---

<div class="post-metadata">

**Author:** ![kilivor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@kilivor](https://www.ruby-forum.com/u/kilivor)\
**Post date:** [August 8, 2006, 11:38am UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857/3 "2006-08-08T11:38:18Z")

</div>

On Tue, 08 Aug 2006 18:19:12 +0900, Kilivor K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> end
> 
> So I want to know the names of A subclasses: A1 and A2. Then instantiate  
> via reflection. Is it possible?
> 
> Using ObjectSpace it is possible to know all the instantiated objects of  
> a class. But here no objects yet.

This is a fun pattern that I use a lot.  
Here is a simple code snippet using ObjectSpace:

subclasses = []  
ObjectSpace.each\_object(Class) do |klass|  
if klass != A && klass.ancestors.include?(A)  
subclasses \<\< klass  
end  
end

# Then you can create new instances by calling new on the class

subclases.each do |klass|  
klass.new  
end

Cheers,  
Zev

---

<div class="post-metadata">

**Author:** ![kilivor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@kilivor](https://www.ruby-forum.com/u/kilivor)\
**Post date:** [August 8, 2006, 11:39am UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857/4 "2006-08-08T11:39:08Z")

</div>

Mauricio F. wrote:

> […]  
> You can use @@subclasses if you want A.subclasses to include A1b:  
> […]

Thanks / gracias!!!

---

<div class="post-metadata">

**Author:** ![kilivor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@kilivor](https://www.ruby-forum.com/u/kilivor)\
**Post date:** [August 8, 2006, 12:32pm UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857/5 "2006-08-08T12:32:23Z")

</div>

Kilivor K. wrote:

> class A2 \<A  
> end
> 
> So I want to know the names of A subclasses: A1 and A2. Then instantiate  
> via reflection. Is it possible?

class Class  
def inherited(subclass)  
subclasses.push(subclass)  
end

```
 def subclasses
   @subclasses ||= []
 end

```

end

class A; end  
class B \< A; end  
class C \< A; end

A.subclasses =\> [B, C]  
instances = A.subclasses.map{|subclass| subclass.new }

Cheers,  
Daniel

---

<div class="post-metadata">

**Author:** ![kilivor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@kilivor](https://www.ruby-forum.com/u/kilivor)\
**Post date:** [August 8, 2006, 3:02pm UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857/6 "2006-08-08T15:02:45Z")

</div>

Daniel S. wrote:

> class Class  
> def inherited(subclass)  
> subclasses.push(subclass)  
> end
> 
> ```
> def subclasses
> @subclasses ||= []
> end
> 
> ```
> 
> end

Now that I think about it, this may be better:

class Class  
def inherited(subclass)  
(@subclasses ||= []).push(subclass)  
end

```
 def subclasses
   (@subclasses ||= []).dup
 end

```

end

That way you can somewhat avoid the problems given by

A.subclasses.push(UnrelatedClass)

Cheers,  
Daniel

---

<div class="post-metadata">

**Author:** ![kilivor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@kilivor](https://www.ruby-forum.com/u/kilivor)\
**Post date:** [August 8, 2006, 3:14pm UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857/7 "2006-08-08T15:14:47Z")

</div>

On Tue, 08 Aug 2006 18:32:24 +0900, Mauricio F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> On Tue, Aug 08, 2006 at 06:19:12PM +0900, Kilivor K. wrote:

> > So I want to know the names of A subclasses: A1 and A2. Then instantiate  
> > via reflection. Is it possible?
> 
> class A  
> class \<\< self; attr\_reader :subclasses end  
> def self.inherited(x); (@subclasses ||= []) \<\< x end  
> end

I am sure Mauricio knows this, but just in case others don’t. If you  
use this particular solution a lot you might also want to call super,  
because your class might inherit from another class that also wants to  
use the inherited method. A simple change to fix this is:

def self.inherited(x); (@subclasses ||= []) \<\< x; super; end

Cheers,  
Zev

---

<div class="post-metadata">

**Author:** ![kilivor](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/77aa72/32.png) [@kilivor](https://www.ruby-forum.com/u/kilivor)\
**Post date:** [August 15, 2006, 2:19pm UTC](https://www.ruby-forum.com/t/automatic-instantiation-of-subclasses/101857/8 "2006-08-15T14:19:23Z")

</div>

Sorry for answering late, I’ve been away for a week.

Kilivor K. schrieb:

> end
> 
> So I want to know the names of A subclasses: A1 and A2. Then instantiate  
> via reflection. Is it possible?
> 
> Using ObjectSpace it is possible to know all the instantiated objects of  
> a class. But here no objects yet.

In Ruby, classes are first-class objects 😉

ObjectSpace.each\_object( class \<\< A; self; end ) do |c|  
p c  
end

Regards,  
Pit
