From: Joel VanderWerf Date: 2006-02-16T18:44:11+09:00 Subject: Re: Creating objects without knowing their names 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 # ["SOME_CONSTANT", "MyWeirdClass"] [#::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