# Creating objects without knowing their names

**URL:** <https://www.ruby-forum.com/t/creating-objects-without-knowing-their-names/53898>\
**Category:** Ruby\
**Created:** [February 16, 2006, 10:10am UTC](https://www.ruby-forum.com/t/creating-objects-without-knowing-their-names/53898 "2006-02-16T10:10:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 16, 2006, 10:10am UTC](https://www.ruby-forum.com/t/creating-objects-without-knowing-their-names/53898/1 "2006-02-16T10:10:33Z")

</div>

Hi

I’d like to load an arbitary number of Ruby files from a directory and  
create their associated objects. However, I don’t know the class names  
of the files that have just been loaded. Is it possible to determine a  
file’s class name once that file has been loaded? (Without resorting to  
parsing, or enforcing a mapping between the filename and class name.)

What I want to do is something like the following:

```
converter_names = Array.new
Find.find("./converters") do |filename|
  converter_names.push(filename) if filename =~ /rb$/
end

converters = Array.new
converter_names.each do |converter_name|
  load converter_name
  klassName = ...?
  converters.push(Object.const_get(klassName).new)
end

```

Many thanks

Paul

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 16, 2006, 10:46am UTC](https://www.ruby-forum.com/t/creating-objects-without-knowing-their-names/53898/2 "2006-02-16T10:46:46Z")

</div>

removed\_email\_address@domain.invalid wrote:

> ```
> converter_names = Array.new
> Find.find("./converters") do |filename|
> converter_names.push(filename) if filename =~ /rb$/
> end
> 
> converters = Array.new
> converter_names.each do |converter_name|
> load converter_name
> klassName = ...?
> converters.push(Object.const_get(klassName).new)
> end
> 
> ```

You probably know this already, but for the benefit of bystanders: there  
isn’t in general one-to-one mapping between classes and files. A class  
can be defined across several files; a file can contain several class  
definitions. (Maybe in the case of the files you are using there is  
always a 1-1 map, though.)

I like to use module\_eval to solve this problem by reading the file and  
evaling its definitions in the context of a new module. It’s all wrapped  
up neatly in my “script” library on RAA.

For example:

$ cat cl.rb  
class MyWeirdClass  
def foo  
end  
end

SOME\_CONSTANT = 3

$ cat script-ex.rb  
require ‘script’

script = Script.load “cl.rb”

p script  
p script.constants  
script\_objects = script.constants.map {|k| script.const\_get(k)}  
script\_classes = script\_objects.grep(Class)  
p script\_classes

$ ruby script-ex.rb  
#Script:/home/vjoel/ruby/misc/cl.rb  
[“SOME\_CONSTANT”, “MyWeirdClass”]  
[#Script:0xb7d794a4::MyWeirdClass]

This also has the benefit of keeping every name from the external file  
in a new module’s namespace. The return value of Script.load is that  
module.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 16, 2006, 1:50pm UTC](https://www.ruby-forum.com/t/creating-objects-without-knowing-their-names/53898/3 "2006-02-16T13:50:54Z")

</div>

Robert K. wrote:

> overrides #inherited so it gets notified every time a sub class is
> 
> ```
> robert
> 
> ```

Or you can compare the classes you had before loading to classes you  
had after loading. Something like this:

def defined\_classes  
classes = []  
ObjectSpace.each\_object(Class){|c| classes \<\< c}  
classes  
end

initial\_classes = defined\_classes  
require ‘net/http’  
p defined\_classes - initial\_classes

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 16, 2006, 11:50am UTC](https://www.ruby-forum.com/t/creating-objects-without-knowing-their-names/53898/4 "2006-02-16T11:50:22Z")

</div>

Joel VanderWerf wrote:

> removed\_email\_address@domain.invalid wrote:
> 
> > Hi
> > 
> > I’d like to load an arbitary number of Ruby files from a directory  
> > and create their associated objects. However, I don’t know the class  
> > names of the files that have just been loaded. Is it possible to  
> > determine a file’s class name once that file has been loaded?  
> > (Without resorting to parsing, or enforcing a mapping between the  
> > filename and class name.)

> You probably know this already, but for the benefit of bystanders:  
> there isn’t in general one-to-one mapping between classes and files.  
> A class  
> can be defined across several files; a file can contain several class  
> definitions. (Maybe in the case of the files you are using there is  
> always a 1-1 map, though.)

There are other options. Some of them:

- Make sure all classes on those files inherit a base class which  
overrides #inherited so it gets notified every time a sub class is  
created. You can then store the set of sub classes in a member of the  
base class and use that for whatever purposes.

- Make classes in those files register with some arbitrary registry you  
create (that’s basically the same as the first just more explicit).

- use set\_trace\_func to trance execution of those files and notice  
whenever a new class occurs. (Not sure whether that works though).

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 16, 2006, 4:07pm UTC](https://www.ruby-forum.com/t/creating-objects-without-knowing-their-names/53898/5 "2006-02-16T16:07:24Z")

</div>

All very helpful answers. Many thanks indeed.  
Paul

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [February 16, 2006, 7:24pm UTC](https://www.ruby-forum.com/t/creating-objects-without-knowing-their-names/53898/6 "2006-02-16T19:24:01Z")

</div>

removed\_email\_address@domain.invalid wrote:

> require ‘net/http’  
> p defined\_classes - initial\_classes

Unreliable if your “script” files also require libraries. You still have  
to pick out the classes you are looking for.
