# Code introspection

**URL:** <https://rubytalk.org/t/code-introspection/12760>\
**Category:** ruby-talk\
**Created:** [26 July 2004 10:21 UTC](https://rubytalk.org/t/code-introspection/12760 "2004-07-26T10:21:54Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![DCC](https://avatars.discourse-cdn.com/v4/letter/d/50afbb/32.png) [@DCC](https://rubytalk.org/u/DCC)\
**Post date:** [26 July 2004 10:21 UTC](https://rubytalk.org/t/code-introspection/12760/1 "2004-07-26T10:21:54Z")

</div>

Hi,

Is there a solution to do code introspection rather than introspection  
at the level of the Module/Object ? I can't figure out if I'm looking  
for something that isn't there in Ruby since I've been reading C# code  
or if I'm missing something. Let me explain my problem.  
I would like to load ruby source files and dynamically create objects  
from classes located inside these sources. It's one class/object per  
source file and I can make it so that a string from a configuration  
file holds the name of the class. However I can't figure out a good  
way to use that string to get to the class in the source file.

I could use eval but am really uncomfortable with that for obvious  
reasons (people keep saying it's evil so I don't play with him). The  
other solution I came up with was to add a method in the same source  
but outside the class to return the desired object:

--------------source file---------  
class MyNewClass  
....  
end

def create\_loaded\_class()  
&nbsp;&nbsp;return MyNewClass.new()  
end

> **···**
>
> ---------------------------------
> 
> Then as I require the source files I can successively invoke the  
> create\_loaded\_class method. This works but can get quite messy as  
> there are a lot of things to consider if you need to reload sources  
> and create new objects etc.  
> Please tell me I'm missing something obvious :).
> 
> thanks,  
> Daniel

---

<div class="post-metadata">

**Author:** ![Laurent\_Julliard4](https://avatars.discourse-cdn.com/v4/letter/l/ebca7d/32.png) [@Laurent\_Julliard4](https://rubytalk.org/u/Laurent_Julliard4)\
**Post date:** [26 July 2004 10:31 UTC](https://rubytalk.org/t/code-introspection/12760/2 "2004-07-26T10:31:51Z")

</div>

> I would like to load ruby source files and dynamically create objects  
> from classes located inside these sources. It's one class/object per  
> source file and I can make it so that a string from a configuration  
> file holds the name of the class. However I can't figure out a good  
> way to use that string to get to the class in the source file.

something like:

'Myclass' in 'Myclass.rb' or the file names are not related

> I could use eval but am really uncomfortable with that for obvious  
> reasons (people keep saying it's evil so I don't play with him). The  
> other solution I came up with was to add a method in the same source  
> but outside the class to return the desired object:

you may use const\_get:

> > class Foo  
> > end

=\> nil

> > Object::const\_get('Foo').new

=\> #\<Foo:0x28b3eb8\>

> **···**
>
> il 26 Jul 2004 03:19:36 -0700, daniel@danielcremer.com (Daniel Cremer) ha scritto::

---

<div class="post-metadata">

**Author:** ![Sam\_McCall](https://avatars.discourse-cdn.com/v4/letter/s/e56c9b/32.png) [@Sam\_McCall](https://rubytalk.org/u/Sam_McCall)\
**Post date:** [26 July 2004 10:31 UTC](https://rubytalk.org/t/code-introspection/12760/3 "2004-07-26T10:31:58Z")

</div>

How about Object.const\_get("MyClass").new ?  
Sam

---

<div class="post-metadata">

**Author:** ![Lothar\_Scholz2](https://avatars.discourse-cdn.com/v4/letter/l/f14d63/32.png) [@Lothar\_Scholz2](https://rubytalk.org/u/Lothar_Scholz2)\
**Post date:** [26 July 2004 11:10 UTC](https://rubytalk.org/t/code-introspection/12760/4 "2004-07-26T11:10:20Z")

</div>

Hello Daniel,

> Is there a solution to do code introspection rather than introspection  
> at the level of the Module/Object ? I can't figure out if I'm looking

Yes but only from the C level. You need to create the "Node" tree and  
travere it. Unfortuneatly there seems to be no visitor pattern class to do  
this and you must expect that the Node structure can change even  
between minor updates a lot. So read the code in eval.c and parse.c.

Look at the ExErb project for an application that does this.

Programming is easy if you are an experienced programmer but  
maintainance is quite some work.

> **···**
>
> --  
> Best regards, emailto: scholz at scriptolutions dot com  
> Lothar Scholz [http://www.ruby-ide.com](http://www.ruby-ide.com)  
> CTO Scriptolutions Ruby, PHP, Python IDE 's

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard3](https://avatars.discourse-cdn.com/v4/letter/a/7cd45c/32.png) [@Ara.T.Howard3](https://rubytalk.org/u/Ara.T.Howard3)\
**Post date:** [26 July 2004 13:41 UTC](https://rubytalk.org/t/code-introspection/12760/5 "2004-07-26T13:41:54Z")

</div>

~ \> cat c.rb  
&nbsp;&nbsp;&nbsp;files = %w(a.rb b.rb)

&nbsp;&nbsp;&nbsp;files.each do |file|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;load file  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name, klass = Common.introspect file  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p klass  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;klass.new  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;~ \> ruby c.rb  
&nbsp;&nbsp;&nbsp;"Foo"  
&nbsp;&nbsp;&nbsp;Common::Foo  
&nbsp;&nbsp;&nbsp;"foo"  
&nbsp;&nbsp;&nbsp;"Bar"  
&nbsp;&nbsp;&nbsp;Common::Bar  
&nbsp;&nbsp;&nbsp;"bar"

&nbsp;&nbsp;&nbsp;~ \> cat a.rb  
&nbsp;&nbsp;&nbsp;module Common  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class Foo  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p 'foo'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class \<\< self  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def introspect path  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@introspect[File.basename(path)]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@introspect = {} unless defined? @introspect  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@introspect[File.basename(\_\_FILE\_\_)] = 'Foo', Foo  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;~ \> cat b.rb  
&nbsp;&nbsp;&nbsp;module Common  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class Bar  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def initialize  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p 'bar'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class \<\< self  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def introspect path  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@introspect[File.basename(path)]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@introspect = {} unless defined? @introspect  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@introspect[File.basename(\_\_FILE\_\_)] = 'Bar', Bar  
&nbsp;&nbsp;&nbsp;end

you could obviously do this without the 'Common' module - but i think it's  
cleaner/safer this way - provided you can manage to wrap all your modules this  
way...

kind regards.

-a

> **···**
>
> On Mon, 26 Jul 2004, Daniel Cremer wrote:
> 
> > Hi,
> > 
> > Is there a solution to do code introspection rather than introspection  
> > at the level of the Module/Object ? I can't figure out if I'm looking  
> > for something that isn't there in Ruby since I've been reading C# code  
> > or if I'm missing something. Let me explain my problem.  
> > I would like to load ruby source files and dynamically create objects  
> > from classes located inside these sources. It's one class/object per  
> > source file and I can make it so that a string from a configuration  
> > file holds the name of the class. However I can't figure out a good  
> > way to use that string to get to the class in the source file.
> > 
> > I could use eval but am really uncomfortable with that for obvious  
> > reasons (people keep saying it's evil so I don't play with him). The  
> > other solution I came up with was to add a method in the same source  
> > but outside the class to return the desired object:
> > 
> > --------------source file---------  
> > class MyNewClass  
> > ...  
> > end
> > 
> > def create\_loaded\_class()  
> > return MyNewClass.new()  
> > end  
> > ---------------------------------
> > 
> > Then as I require the source files I can successively invoke the  
> > create\_loaded\_class method. This works but can get quite messy as  
> > there are a lot of things to consider if you need to reload sources  
> > and create new objects etc.  
> > Please tell me I'm missing something obvious :).
> > 
> > thanks,  
> > Daniel
> 
> # --
> 
> > EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov  
> > PHONE :: 303.497.6469  
> > A flower falls, even though we love it;  
> > and a weed grows, even though we do not love it. --Dogen
> 
> ===============================================================================

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [26 July 2004 13:16 UTC](https://rubytalk.org/t/code-introspection/12760/6 "2004-07-26T13:16:53Z")

</div>

"Lothar Scholz" \<mailinglists@scriptolutions.com\> schrieb im Newsbeitrag  
news:178359988968.20040726131022@scriptolutions.com...

> Hello Daniel,
> 
> \> Is there a solution to do code introspection rather than

introspection

> \> at the level of the Module/Object ? I can't figure out if I'm

looking

> Yes but only from the C level. You need to create the "Node" tree and  
> travere it. Unfortuneatly there seems to be no visitor pattern class to

do

> this and you must expect that the Node structure can change even  
> between minor updates a lot. So read the code in eval.c and parse.c.

Err, I think this is overkill. Daniel just wants to create an instance of  
a class whose name he knows. So the already suggested Object.const\_get(  
class\_name ) or ObjectSpace.const\_get( class\_name ) suffices.

If you don't know class names beforehand, you can work with an anonymous  
module as wrapper like this:

mod = Module.new  
mod.class\_eval( File.read( "foo.rb" ) )  
new\_classes = mod.constants.inject() {|ar,c| cl=mod.const\_get(c); ar \<\<  
cl if Class === cl; ar}  
p new\_classes  
include mod  
p Foo

Or even do this

mod = Object  
mod.class\_eval( File.read( "foo.rb" ) )  
classes = mod.constants.inject() {|ar,c| cl=mod.const\_get(c); ar \<\< cl  
if Class === cl; ar}  
p classes  
p Foo

Regards

&nbsp;&nbsp;&nbsp;&nbsp;robert

---

<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:** [26 July 2004 20:36 UTC](https://rubytalk.org/t/code-introspection/12760/7 "2004-07-26T20:36:44Z")

</div>

Using module\_eval in the context of a wrapper module is one way to go. (I know you said no eval, but load/require end up eval-ing, anyway. I guess you could do something with $SAFE if you are worried about mischief.)

This has gotten so common for me that I put it in a small lib: [http://redshift.sourceforge.net/script\](http://redshift.sourceforge.net/script%5C). Here's a way of using it for what you want to do:

--- program.rb ---

require 'script'

files = ["dog.rb", "cat.rb"]

files.each do |file|  
&nbsp;&nbsp;&nbsp;animal\_wrapper = Script.load(file)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# animal\_wrapper is a Module in whose context the top-level  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# constants and methods are defined.

&nbsp;&nbsp;&nbsp;p animal\_wrapper.main\_file # should be same as the file local var  
&nbsp;&nbsp;&nbsp;p animal\_wrapper::CLASS # top-level constant in the script  
&nbsp;&nbsp;&nbsp;p animal\_wrapper.make\_animal # top-level meth in the script  
end

--- dog.rb ---

class Dog  
&nbsp;&nbsp;&nbsp;def initialize name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name = name  
&nbsp;&nbsp;&nbsp;end  
end

CLASS = Dog

def make\_animal  
&nbsp;&nbsp;&nbsp;Dog.new "Rover"  
end

--- cat.rb ---

class Dog  
&nbsp;&nbsp;&nbsp;def initialize name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name = name  
&nbsp;&nbsp;&nbsp;end  
end

CLASS = Dog

def make\_animal  
&nbsp;&nbsp;&nbsp;Dog.new "Rover"  
end

--- output of program.rb ---

"/home/vjoel/tmp/script-example/dog.rb"  
#\<Script:0x401c4e3c\>::Dog  
#\<#\<Script:0x401c4e3c\>:🐕0x401c4964 @name="Rover"\>  
"/home/vjoel/tmp/script-example/cat.rb"  
#\<Script:0x401c4928\>::Cat  
#\<#\<Script:0x401c4928\>:🐈0x401c4450 @name="Fuzzy"\>

> **···**
>
> > On Mon, 26 Jul 2004, Daniel Cremer wrote:
> > 
> > > Hi,
> > > 
> > > Is there a solution to do code introspection rather than introspection  
> > > at the level of the Module/Object ? I can't figure out if I'm looking  
> > > for something that isn't there in Ruby since I've been reading C# code  
> > > or if I'm missing something. Let me explain my problem.  
> > > I would like to load ruby source files and dynamically create objects  
> > > from classes located inside these sources. It's one class/object per  
> > > source file and I can make it so that a string from a configuration  
> > > file holds the name of the class. However I can't figure out a good  
> > > way to use that string to get to the class in the source file.
> > > 
> > > I could use eval but am really uncomfortable with that for obvious  
> > > reasons (people keep saying it's evil so I don't play with him). The  
> > > other solution I came up with was to add a method in the same source  
> > > but outside the class to return the desired object:
> > > 
> > > --------------source file---------  
> > > class MyNewClass  
> > > ...  
> > > end
> > > 
> > > def create\_loaded\_class()  
> > > return MyNewClass.new()  
> > > end  
> > > ---------------------------------
> > > 
> > > Then as I require the source files I can successively invoke the  
> > > create\_loaded\_class method. This works but can get quite messy as  
> > > there are a lot of things to consider if you need to reload sources  
> > > and create new objects etc.  
> > > Please tell me I'm missing something obvious :).
> 
> --------
> 
> (You might want Dog and Cat to inherit from some base class that has a self.to\_s method to avoid the hex junk.)
> 
> You could simplify the picture by defining the \_same\_ class in each script file:
> 
> class Animal  
> &nbsp;&nbsp;&nbsp;def initialize;...;end  
> end
> 
> and then you can reference it by
> 
> &nbsp;&nbsp;&nbsp;animal\_wrapper::Animal.new
> 
> in your main program. The fact that dog.rb and cat.rb are loaded into different wrapper contexts keeps these classes distinct, even though their names appear the same.

---

<div class="post-metadata">

**Author:** ![DCC](https://avatars.discourse-cdn.com/v4/letter/d/50afbb/32.png) [@DCC](https://rubytalk.org/u/DCC)\
**Post date:** [26 July 2004 14:56 UTC](https://rubytalk.org/t/code-introspection/12760/8 "2004-07-26T14:56:40Z")

</div>

ahh... it looks like creating an anonymous module is the piece that is  
really missing for me at the moment...  
thanks for the ideas, I'm not sure how far I'll have to carry this so  
they're all appreciated

&nbsp;&nbsp;-Daniel

> **···**
>
> On Mon, 2004-07-26 at 14:16, Robert Klemme wrote:
> 
> > "Lothar Scholz" \<mailinglists@scriptolutions.com\> schrieb im Newsbeitrag  
> > news:178359988968.20040726131022@scriptolutions.com...  
> > \> Hello Daniel,  
> > \>  
> > \> \> Is there a solution to do code introspection rather than  
> > introspection  
> > \> \> at the level of the Module/Object ? I can't figure out if I'm  
> > looking  
> > \>  
> > \> Yes but only from the C level. You need to create the "Node" tree and  
> > \> travere it. Unfortuneatly there seems to be no visitor pattern class to  
> > do  
> > \> this and you must expect that the Node structure can change even  
> > \> between minor updates a lot. So read the code in eval.c and parse.c.
> > 
> > Err, I think this is overkill. Daniel just wants to create an instance of  
> > a class whose name he knows. So the already suggested Object.const\_get(  
> > class\_name ) or ObjectSpace.const\_get( class\_name ) suffices.
> > 
> > If you don't know class names beforehand, you can work with an anonymous  
> > module as wrapper like this:
> > 
> > mod = Module.new  
> > mod.class\_eval( File.read( "foo.rb" ) )  
> > new\_classes = mod.constants.inject() {|ar,c| cl=mod.const\_get(c); ar \<\<  
> > cl if Class === cl; ar}  
> > p new\_classes  
> > include mod  
> > p Foo
> > 
> > (...)

---

<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:** [26 July 2004 20:48 UTC](https://rubytalk.org/t/code-introspection/12760/9 "2004-07-26T20:48:09Z")

</div>

Joel VanderWerf wrote:

> --- cat.rb ---
> 
> class Dog  
> &nbsp;&nbsp;def initialize name  
> &nbsp;&nbsp;&nbsp;&nbsp;@name = name  
> &nbsp;&nbsp;end  
> end
> 
> CLASS = Dog
> 
> def make\_animal  
> &nbsp;&nbsp;Dog.new "Rover"  
> end

Ooops. Copy/paste error.

--- cat.rb ---

class Cat  
&nbsp;&nbsp;&nbsp;def initialize name  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@name = name  
&nbsp;&nbsp;&nbsp;end  
end

CLASS = Cat

def make\_animal  
&nbsp;&nbsp;&nbsp;Cat.new "Fuzzy"  
end

---

<div class="post-metadata">

**Author:** ![Laurent\_Julliard4](https://avatars.discourse-cdn.com/v4/letter/l/ebca7d/32.png) [@Laurent\_Julliard4](https://rubytalk.org/u/Laurent_Julliard4)\
**Post date:** [27 July 2004 13:06 UTC](https://rubytalk.org/t/code-introspection/12760/10 "2004-07-27T13:06:50Z")

</div>

well, than take a look at the simple load:

&nbsp;&nbsp;&nbsp;&nbsp;load(filename, wrap=false) =\> true

> **···**
>
> il Mon, 26 Jul 2004 23:56:40 +0900, Daniel Cremer \<daniel@danielcremer.com\> ha scritto::
> 
> > > If you don't know class names beforehand, you can work with an anonymous  
> > > module as wrapper like this:
> > > 
> > > mod = Module.new  
> > > mod.class\_eval( File.read( "foo.rb" ) )  
> > > new\_classes = mod.constants.inject() {|ar,c| cl=mod.const\_get(c); ar \<\<  
> > > cl if Class === cl; ar}  
> > > p new\_classes  
> > > include mod  
> > > p Foo
> > > 
> > > (...)
> > 
> > ahh... it looks like creating an anonymous module is the piece that is  
> > really missing for me at the moment...  
> > thanks for the ideas, I'm not sure how far I'll have to carry this so  
> > they're all appreciated
> 
> -----------------------------------------------------------------------  
> &nbsp;&nbsp;&nbsp;&nbsp;Loads and executes the Ruby program in the file \_filename\_. If the  
> &nbsp;&nbsp;&nbsp;&nbsp;filename does not resolve to an absolute path, the file is  
> searched  
> &nbsp;&nbsp;&nbsp;&nbsp;for in the library directories listed in +$:+. If the optional  
> &nbsp;&nbsp;&nbsp;&nbsp;\_wrap\_ parameter is +true+, the loaded script will be executed  
> &nbsp;&nbsp;&nbsp;&nbsp;under an anonymous module, protecting the calling program's global  
> &nbsp;&nbsp;&nbsp;&nbsp;namespace. In no circumstance will any local variables in the  
> &nbsp;&nbsp;&nbsp;&nbsp;loaded file be propagated to the loading environment.

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [29 July 2004 09:36 UTC](https://rubytalk.org/t/code-introspection/12760/11 "2004-07-29T09:36:52Z")

</div>

"gabriele renzi" \<surrender\_it@remove.yahoo.it\> schrieb im Newsbeitrag  
news:rkjcg0tf6o9g63lnb6lo9gk5bsjvg82kcd@4ax.com...

> \>\> If you don't know class names beforehand, you can work with an

anonymous

> \>\> module as wrapper like this:  
> \>\>  
> \>\> mod = Module.new  
> \>\> mod.class\_eval( File.read( "foo.rb" ) )  
> \>\> new\_classes = mod.constants.inject() {|ar,c| cl=mod.const\_get(c);

ar \<\<

> \>\> cl if Class === cl; ar}  
> \>\> p new\_classes  
> \>\> include mod  
> \>\> p Foo  
> \>\>  
> \>\> (...)  
> \>  
> \>ahh... it looks like creating an anonymous module is the piece that is  
> \>really missing for me at the moment...  
> \>thanks for the ideas, I'm not sure how far I'll have to carry this so  
> \>they're all appreciated  
> \>
> 
> well, than take a look at the simple load:
> 
> &nbsp;&nbsp;&nbsp;&nbsp;load(filename, wrap=false) =\> true  
> -----------------------------------------------------------------------  
> &nbsp;&nbsp;&nbsp;&nbsp;Loads and executes the Ruby program in the file \_filename\_. If the  
> &nbsp;&nbsp;&nbsp;&nbsp;filename does not resolve to an absolute path, the file is  
> searched  
> &nbsp;&nbsp;&nbsp;&nbsp;for in the library directories listed in +$:+. If the optional  
> &nbsp;&nbsp;&nbsp;&nbsp;\_wrap\_ parameter is +true+, the loaded script will be executed  
> &nbsp;&nbsp;&nbsp;&nbsp;under an anonymous module, protecting the calling program's global  
> &nbsp;&nbsp;&nbsp;&nbsp;namespace. In no circumstance will any local variables in the  
> &nbsp;&nbsp;&nbsp;&nbsp;loaded file be propagated to the loading environment.

Yes, but that doesn't help here since there's no way to find this  
anonymous module in order to find all classes defined in the file. I  
tried that initially, too, but the return value of load is not the module  
but 'true' or 'false'. Or am I missing somethig?

Regards

&nbsp;&nbsp;&nbsp;&nbsp;robert

> **···**
>
> > il Mon, 26 Jul 2004 23:56:40 +0900, Daniel Cremer \> \<daniel@danielcremer.com\> ha scritto::

---

<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:** [29 July 2004 17:33 UTC](https://rubytalk.org/t/code-introspection/12760/12 "2004-07-29T17:33:30Z")

</div>

Robert Klemme wrote:

> "gabriele renzi" \<surrender\_it@remove.yahoo.it\> schrieb im Newsbeitrag  
> news:rkjcg0tf6o9g63lnb6lo9gk5bsjvg82kcd@4ax.com...

...

> > &nbsp;&nbsp;&nbsp;load(filename, wrap=false) =\> true  
> > -----------------------------------------------------------------------  
> > &nbsp;&nbsp;&nbsp;Loads and executes the Ruby program in the file \_filename\_. If the  
> > &nbsp;&nbsp;&nbsp;filename does not resolve to an absolute path, the file is  
> > searched  
> > &nbsp;&nbsp;&nbsp;for in the library directories listed in +$:+. If the optional  
> > &nbsp;&nbsp;&nbsp;\_wrap\_ parameter is +true+, the loaded script will be executed  
> > &nbsp;&nbsp;&nbsp;under an anonymous module, protecting the calling program's global  
> > &nbsp;&nbsp;&nbsp;namespace. In no circumstance will any local variables in the  
> > &nbsp;&nbsp;&nbsp;loaded file be propagated to the loading environment.
> 
> Yes, but that doesn't help here since there's no way to find this  
> anonymous module in order to find all classes defined in the file. I  
> tried that initially, too, but the return value of load is not the module  
> but 'true' or 'false'. Or am I missing somethig?

The anonymous module is not even reachable, so it will get GC-ed, as in this example:

irb(main):002:0\> def foo; load "f.rb", true; end  
=\> nil  
irb(main):003:0\> ObjectSpace.each\_object(Module){}  
=\> 372  
irb(main):004:0\> foo  
=\> true  
irb(main):005:0\> ObjectSpace.each\_object(Module){}  
=\> 373  
irb(main):006:0\> foo  
=\> true  
irb(main):007:0\> ObjectSpace.each\_object(Module){}  
=\> 374  
irb(main):008:0\> GC.start  
=\> nil  
irb(main):009:0\> ObjectSpace.each\_object(Module){}  
=\> 372

Getting one's hands on the wrapper module is the raison d'etre of my little "script" lib ([http://redshift.sourceforge.net/script\](http://redshift.sourceforge.net/script%5C)). More simply, you can just read the file and use module\_eval (but script adds some features).
