3

ruby で「require 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

1 つのアプローチは、ファイルを要求する前に、 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 に答える