Question

In ruby, if I do "require foo", is there a way to subsequently determine the name of the module or modules defined in foo.rb?

For example, say I have a ruby file named foo.rb that looks like this:

# foo.rb
module MyModule
    def self.summary
        "this does something useful"
    end
    ...
end

In another script, after I do "require foo", how can I determine that I now have a module named MyModule?

Ultimate what I'm after is to be able to do something like this:

file = someComputedFileName()
require file
puts "summary of #{file}: #{???::summary}

While I could force myself to make module names and file names identical, I'd rather not. I want a bit more freedom in making short filenames but more expressive module names. However, I am guaranteeing to myself that each file will only define a single module (think: plugins).

Was it helpful?

Solution

One approach would be to use ObjectSpace.each_object(Module) to find all defined modules before requiring the file. Then, after you require the file, loop over all defined modules again and see if there are any new ones.

require "set"
old_modules = SortedSet.new
ObjectSpace.each_object(Module) {|m| old_modules.add(m) }

file = someComputedFileName()
require file

new_modules = SortedSet.new
ObjectSpace.each_object(Module) {|m| new_modules.add(m) unless old_modules.include?(m) }

puts "summary of #{file}: #{new_modules.to_a.map{|m|m.summary}.join(',')}"

That would also let you define more than one module in the file.

OTHER TIPS

I don't know if this is the best solution, but off the top of my head this seems to work:

all_constants = Object.constants
require 'foo'

foo_constants = Object.constants - all_constants

foo_constants should give you only the modules, classes or other constants that were defined by foo.rb.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top