2010-08-15 17 views
17

Comment listeriez-vous les modules qui ont été inclus dans une classe spécifique dans une hiérarchie de classes dans Ruby? Quelque chose comme ceci:Comment lister les modules inclus dans une classe Ruby?

module SomeModule 
end 

class ParentModel < Object 
    include SomeModule 
end 

class ChildModel < ParentModel 
end 

p ChildModel.included_modules #=> [SomeModule] 
p ChildModel.included_modules(false) #=> [] 

Liste des ancêtres fait plus apparaître le module dans l'arbre:

p ChildModel.ancestors #=> [ChildModel, ParentModel, SomeModule, Object, Kernel] 

Répondre

16

Pour autant que je comprends votre question, quelque chose comme ceci est ce que vous cherchez:

class Class 
    def mixin_ancestors(include_ancestors=true) 
    ancestors.take_while {|a| include_ancestors || a != superclass }. 
    select {|ancestor| ancestor.instance_of?(Module) } 
    end 
end 

Cependant, je ne comprends pas parfaitement vos cas de test: pourquoi SomeModule est-il listé comme module inclus de ChildModel même si n'est pas effectivement inclus dans ChildModel mais dans ParentModel? Et inversement, pourquoi Kerneln'est pas listé comme un module inclus, même s'il est tout autant dans la chaîne des ancêtres que SomeModule? Et que signifie l'argument booléen de la méthode?

(Notez que les arguments booléens sont toujours mauvaise conception:. Une méthode doit faire exactement une chose Si cela prend un argument booléen, il fait par définition deux choses, l'une si l'argument est vrai, une autre est le l'argument est faux ou, s'il ne fait qu'une chose, alors cela ne peut que signifier qu'il ignore son argument, auquel cas il ne devrait pas le prendre pour commencer.)

+0

Je ne suis pas l'affiche originale, mais Je pense que je peux répondre à votre question re: l'argument booléen. Lance s'attend à ce que cette méthode '.included_modules' se comporte comme' # methods', '# public_methods' et d'autres méthodes similaires dans Ruby. Sur ceux-ci, une valeur 'true' signifie" montrez-moi les méthodes que cet objet a obtenu de sa classe EN PLUS DE celles qu'il a reçues de ses classes ancêtres et inclus des modules ". Une valeur false ne renvoie pas ces méthodes supplémentaires. – pablobm