Joel VanderWerf
2/16/2006 9:44:00 AM
paul.p.carey@gmail.com 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.)
>
> 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
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.
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407