2009-01-16 9 views
3

Dans ruby, si je fais "require foo", existe-t-il un moyen de déterminer par la suite le nom du module ou des modules définis dans foo.rb?dans ruby, comment puis-je savoir quel module est défini comme le résultat d'un 'load' ou 'require'?

Par exemple, dire que j'ai un fichier nommé Ruby foo.rb qui ressemble à ceci:

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

Dans un autre script, après que je fais « require foo », comment puis-je déterminer que j'ai maintenant une module nommé MyModule?

Ultime ce que je suis après est de pouvoir faire quelque chose comme ceci:

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

Pendant que je pouvais me forcer à faire des noms de modules et les noms de fichiers identiques, je préfère ne pas. Je veux un peu plus de liberté pour créer des noms de fichiers courts mais des noms de modules plus expressifs. Cependant, je me garantis que chaque fichier ne définira qu'un seul module (think: plugins).

Répondre

3

Une approche serait d'utiliser ObjectSpace .each_object (Module) pour trouver tous les modules définis avant de demander le fichier. Ensuite, après avoir demandé le fichier, bouclez à nouveau sur tous les modules définis et voyez s'il y en a de nouveaux.

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

Cela vous permet également de définir plus d'un module dans le fichier.

+1

Ou simplement utiliser des ensembles et examiner ce qui reste après new_modules.subtract (old_modules)? –

4

Je ne sais pas si cela est la meilleure solution, mais du haut de ma tête cela semble fonctionner:

all_constants = Object.constants 
require 'foo' 

foo_constants = Object.constants - all_constants 

foo_constants devrait vous donner uniquement les modules, les classes ou d'autres constantes qui ont été définies par foo.rb.

+2

qui fonctionne très bien pour les modules de niveau supérieur, mais pas pour les sous-modules. Si vous préférez des modules de haut niveau, c'est une solution beaucoup plus propre –

+0

Ah, vous avez raison, je n'y avais pas pensé. Je n'ai pas vu votre solution avant de l'avoir publiée, mais elle semble beaucoup plus robuste. –

+0

Un autre problème avec ceci est que si mon sous-module nécessite d'autres modules, ceux-ci apparaîtront dans les résultats. Je pense que ma solution sera pour chaque plugin d'écrire leur nom dans une variable globale. Pas la meilleure solution, mais je n'ai pas besoin du meilleur, juste celui qui fonctionne. –

Questions connexes