3

在 ruby​​ 中,如果我确实“需要 foo”,有没有办法随后确定 foo.rb 中定义的一个或多个模块的名称?

例如,假设我有一个名为 foo.rb 的 ruby​​ 文件,如下所示:

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

在另一个脚本中,在我执行“require foo”之后,如何确定我现在有一个名为 MyModule 的模块?

最终我追求的是能够做这样的事情:

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

虽然我可以强迫自己使模块名和文件名相同,但我宁愿不这样做。我希望在制作短文件名时更加自由,但模块名称更具表现力。但是,我向自己保证每个文件只会定义一个模块(想想:插件)。

4

2 回答 2

4

我不知道这是否是最好的解决方案,但在我看来这似乎可行:

all_constants = Object.constants
require 'foo'

foo_constants = Object.constants - all_constants

foo_constants 应该只为您提供由 foo.rb 定义的模块、类或其他常量。

于 2009-01-16T18:19:32.403 回答
3

一种方法是使用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(',')}"

这也可以让您在文件中定义多个模块。

于 2009-01-16T18:17:05.340 回答