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
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
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).