в ruby, как я могу узнать, какой модуль определен как результат 'load' или 'require'? - PullRequest
3 голосов
/ 16 января 2009

В ruby, если я действительно "требую foo", есть ли способ впоследствии определить имя модуля или модулей, определенных в foo.rb?

Например, скажем, у меня есть файл ruby ​​с именем foo.rb, который выглядит следующим образом:

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

В другом скрипте, после того как я "требуемый foo", как я могу определить, что у меня теперь есть модуль с именем MyModule?

В конечном итоге я хочу сделать что-то вроде этого:

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

Хотя я мог заставить себя сделать имена модулей и имена файлов идентичными, я бы не стал. Я хочу немного больше свободы в создании коротких имен файлов, но более выразительных имен модулей. Тем не менее, я гарантирую себе, что каждый файл будет определять только один модуль (подумайте: плагины).

Ответы [ 2 ]

4 голосов
/ 16 января 2009

Я не знаю, является ли это лучшим решением, но мне кажется, что это работает:

all_constants = Object.constants
require 'foo'

foo_constants = Object.constants - all_constants

foo_constants должен содержать только те модули, классы или другие константы, которые были определены foo.rb.

3 голосов
/ 16 января 2009

Один из подходов заключается в использовании ObjectSpace .each_object (Module) для поиска всех определенных модулей, прежде чем запрашивать файл. Затем, после того, как вам потребуется файл, снова переберите все определенные модули и посмотрите, есть ли новые.

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(',')}"

Это также позволит вам определить более одного модуля в файле.

...