# Identfying classes in a file dynamically

**URL:** https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560
**Category:** ruby-talk
**Created:** [10 April 2006 22:21 UTC](https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560 "2006-04-10T22:21:54Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Navya\_Amerineni](https://avatars.discourse-cdn.com/v4/letter/n/df788c/32.png) [@Navya\_Amerineni](https://rubytalk.org/u/Navya_Amerineni)
#### Post date: [10 April 2006 22:21 UTC](https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560/1 "2006-04-10T22:21:54Z")

</div>

Hi,

I was trying to identify the classes in a give file at the run time. the following is the code i used.  
sc, ec = [], []  
ObjectSpace.each\_object(Class) { |c| sc \<\< c }  
require 'Roman.rb'  
ObjectSpace.each\_object(Class) { |c| ec \<\< c }  
new\_classes = ec - sc  
puts new\_classes  
sc, ec = [], []  
ObjectSpace.each\_object(Class) { |c| sc \<\< c }  
require 'Roman1.rb'  
ObjectSpace.each\_object(Class) { |c| ec \<\< c }  
new\_classes = ec - sc  
puts new\_classes

Both roman.rb and roman1.rb has the same class Roman.  
the first time i print the new\_classes i can see the Roman class in the output but the second one does not print because the class Roman is arleady read previously.

is there a way i can over come this problem and identify the Roman class twice.

Thanks,  
Navya.

> **···**
>
> ---------------------------------  
> New Yahoo! Messenger with Voice. Call regular phones from your PC and save big.

---

<div class="post-metadata">

### Author: ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)
#### Post date: [11 April 2006 01:27 UTC](https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560/2 "2006-04-11T01:27:35Z")

</div>

Navya Amerineni wrote:

> Hi,
> 
> I was trying to identify the classes in a give file at the run time. the following is the code i used.  
> sc, ec = ,   
> ObjectSpace.each\_object(Class) { |c| sc \<\< c }  
> require 'Roman.rb'  
> ObjectSpace.each\_object(Class) { |c| ec \<\< c }  
> new\_classes = ec - sc  
> puts new\_classes  
> sc, ec = ,   
> ObjectSpace.each\_object(Class) { |c| sc \<\< c }  
> require 'Roman1.rb'  
> ObjectSpace.each\_object(Class) { |c| ec \<\< c }  
> new\_classes = ec - sc  
> puts new\_classes
> 
> Both roman.rb and roman1.rb has the same class Roman.  
> the first time i print the new\_classes i can see the Roman class in the output but the second one does not print because the class Roman is arleady read previously.
> 
> is there a way i can over come this problem and identify the Roman class twice.

One way is to wrap the file in a module, so that the constants defined  
in it will not collide with other constants.

file = "some/file"  
m = Module.new  
m.module\_eval(IO.read(file), File.expand\_path(file))  
p m.constants

But then the Roman module won't be available except as m::Roman. To fix  
this, you could include m into any class or module that needs to use Roman.

> **···**
>
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

### Author: ![Zach\_Dennis1](https://avatars.discourse-cdn.com/v4/letter/z/ea5d25/32.png) [@Zach\_Dennis1](https://rubytalk.org/u/Zach_Dennis1)
#### Post date: [11 April 2006 13:56 UTC](https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560/3 "2006-04-11T13:56:14Z")

</div>

Navya Amerineni wrote:

> Hi,
> 
> I was trying to identify the classes in a give file at the run time. the following is the code i used.  
> sc, ec = ,   
> ObjectSpace.each\_object(Class) { |c| sc \<\< c }  
> require 'Roman.rb'  
> ObjectSpace.each\_object(Class) { |c| ec \<\< c }  
> new\_classes = ec - sc  
> puts new\_classes  
> sc, ec = ,   
> ObjectSpace.each\_object(Class) { |c| sc \<\< c }  
> require 'Roman1.rb'  
> ObjectSpace.each\_object(Class) { |c| ec \<\< c }  
> new\_classes = ec - sc  
> puts new\_classes
> 
> Both roman.rb and roman1.rb has the same class Roman.  
> the first time i print the new\_classes i can see the Roman class in the output but the second one does not print because the class Roman is arleady read previously.
> 
> is there a way i can over come this problem and identify the Roman class twice.

Way #1, store the new classes in a hash. This way you won't be overriding any classes you've previously loaded.

Way #2, use one array to store new classes, and then each time you compute the "new\_classes" after you load a file, merge those  
into your one authoriatize array. This way you won't be overriding any classes you've previously loaded.

Way #3, pass a string into a new ruby process which loads the files and outputs the new classes. Read these in and then use Way #1  
or Way #2 to store the classes. This is a bit hackish, but it works and it leaves your toplevel ruby process namespace alone.

Here is the idea of Way #3

&nbsp;&nbsp;str =\<\<-'EOT'  
&nbsp;&nbsp;&nbsp;&nbsp;def count\_classes( arg )  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr =   
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectSpace.each\_object( arg ){ |c| arr \<\< c }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arr  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;orig\_classes = count\_classes( Class )  
&nbsp;&nbsp;&nbsp;&nbsp;require "load"  
&nbsp;&nbsp;&nbsp;&nbsp;new\_classes = count\_classes( Class ) - orig\_classes  
&nbsp;&nbsp;&nbsp;&nbsp;puts new\_classes.join( "\n" )  
&nbsp;&nbsp;EOT

&nbsp;&nbsp;child = IO.popen( "ruby -e '#{str}'", "r" )  
&nbsp;&nbsp;new\_classes = child.readlines.map!{ |s| s.chomp! }  
&nbsp;&nbsp;puts new\_classes

Zach

---

<div class="post-metadata">

### Author: ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)
#### Post date: [11 April 2006 02:12 UTC](https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560/4 "2006-04-11T02:12:36Z")

</div>

Hi --

> **···**
>
> On Tue, 11 Apr 2006, Joel VanderWerf wrote:
> 
> > Navya Amerineni wrote:
> > 
> > > Hi,
> > > 
> > > I was trying to identify the classes in a give file at the run time. the following is the code i used.  
> > > sc, ec = ,   
> > > ObjectSpace.each\_object(Class) { |c| sc \<\< c }  
> > > require 'Roman.rb'  
> > > ObjectSpace.each\_object(Class) { |c| ec \<\< c }  
> > > new\_classes = ec - sc  
> > > puts new\_classes  
> > > sc, ec = ,   
> > > ObjectSpace.each\_object(Class) { |c| sc \<\< c }  
> > > require 'Roman1.rb'  
> > > ObjectSpace.each\_object(Class) { |c| ec \<\< c }  
> > > new\_classes = ec - sc  
> > > puts new\_classes
> > > 
> > > Both roman.rb and roman1.rb has the same class Roman.  
> > > the first time i print the new\_classes i can see the Roman class in the output but the second one does not print because the class Roman is arleady read previously.
> > > 
> > > is there a way i can over come this problem and identify the Roman class twice.
> > 
> > One way is to wrap the file in a module, so that the constants defined  
> > in it will not collide with other constants.
> > 
> > file = "some/file"  
> > m = Module.new  
> > m.module\_eval(IO.read(file), File.expand\_path(file))  
> > p m.constants
> > 
> > But then the Roman module won't be available except as m::Roman. To fix  
> > this, you could include m into any class or module that needs to use Roman.
> 
> Also I think that if the read-in file uses the ::Const construct,  
> those classes won't get counted.
> 
> David
> 
> --  
> David A. Black (dblack@wobblini.net)  
> Ruby Power and Light, LLC ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))
> 
> "Ruby for Rails" coming in PDF April 15, and in paper May 5!
> 
> > **[Ruby for Rails](https://www.manning.com/books/ruby-for-rails)**
> >
> > NEWER EDITION AVAILABLE
> > 
> > The Well-Grounded Rubyist, Second Edition is now available. An eBook of the previous edition, The Well-Grounded Rubyist is included at no additional cost when you buy the revised edition! 
> > 
> > 
> > Ruby for Rails helps Rails...

---

<div class="post-metadata">

### Author: ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)
#### Post date: [11 April 2006 02:21 UTC](https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560/5 "2006-04-11T02:21:03Z")

</div>

dblack@wobblini.net wrote:  
...

> Also I think that if the read-in file uses the ::Const construct,  
> those classes won't get counted.

You mean like this:

$ cat t.rb  
class ::Foo  
end  
$ ruby -e 'load "t.rb"; p Foo'  
Foo  
$ ruby -e 'load "t.rb"; ObjectSpace.each\_object(Class) {|c| p c if  
c.name == "Foo"}'  
Foo

So it doesn't look like that works, unless I'm misunderstanding...

> **···**
>
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

### Author: ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)
#### Post date: [11 April 2006 02:47 UTC](https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560/6 "2006-04-11T02:47:09Z")

</div>

Hi --

> **···**
>
> On Tue, 11 Apr 2006, Joel VanderWerf wrote:
> 
> > dblack@wobblini.net wrote:  
> > ...
> > 
> > > Also I think that if the read-in file uses the ::Const construct,  
> > > those classes won't get counted.
> > 
> > You mean like this:
> > 
> > $ cat t.rb  
> > class ::Foo  
> > end  
> > $ ruby -e 'load "t.rb"; p Foo'  
> > Foo  
> > $ ruby -e 'load "t.rb"; ObjectSpace.each\_object(Class) {|c| p c if  
> > c.name == "Foo"}'  
> > Foo
> > 
> > So it doesn't look like that works, unless I'm misunderstanding...
> 
> Yes, that's what I meant; if you have ::Foo in your file, then you  
> won't get a Foo class in the module you wrap in, so you won't get the  
> right count of modules in the file.
> 
> David
> 
> --  
> David A. Black (dblack@wobblini.net)  
> Ruby Power and Light, LLC ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))
> 
> "Ruby for Rails" coming in PDF April 15, and in paper May 5!
> 
> > **[Ruby for Rails](https://www.manning.com/books/ruby-for-rails)**
> >
> > NEWER EDITION AVAILABLE
> > 
> > The Well-Grounded Rubyist, Second Edition is now available. An eBook of the previous edition, The Well-Grounded Rubyist is included at no additional cost when you buy the revised edition! 
> > 
> > 
> > Ruby for Rails helps Rails...

---

<div class="post-metadata">

### Author: ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)
#### Post date: [11 April 2006 03:17 UTC](https://rubytalk.org/t/identfying-classes-in-a-file-dynamically/26560/7 "2006-04-11T03:17:05Z")

</div>

dblack@wobblini.net wrote:

> Hi --
> 
> > ...
> > 
> > > Also I think that if the read-in file uses the ::Const construct,  
> > > those classes won't get counted.
> > 
> > You mean like this:
> > 
> > $ cat t.rb  
> > class ::Foo  
> > end  
> > $ ruby -e 'load "t.rb"; p Foo'  
> > Foo  
> > $ ruby -e 'load "t.rb"; ObjectSpace.each\_object(Class) {|c| p c if  
> > c.name == "Foo"}'  
> > Foo
> > 
> > So it doesn't look like that works, unless I'm misunderstanding...
> 
> Yes, that's what I meant; if you have ::Foo in your file, then you  
> won't get a Foo class in the module you wrap in, so you won't get the  
> right count of modules in the file.

Oh, I see--I thought you meant it was a workaround, but it's actually a  
limitation of the module wrapping trick. Good point.

> **···**
>
> > On Tue, 11 Apr 2006, Joel VanderWerf wrote:
> > 
> > > dblack@wobblini.net wrote:
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
