2009-09-18 6 views
1
Module M 
    Class C 
    end 
end 

Ce que je besoin est quelque chose comme:peut me dire si un rubis Wass de classe donnée définie dans un module donné

M.was_defined_here?(M::C) 
M.classes.include?(M::C) 

Est-ce que cela existe en quelque sorte?

Je sais que je pourrais analyser M :: C.name. Mais quelqu'un pourrait avoir l'idée de changer le nom du module, pour le rendre plus astucieux ou quelque chose comme ça. Je veux une solution propre.

Répondre

3
M.constants.map {|c| M.const_get(c)}.include?(M::C) 

Ou, du commentaire de johannes, en utilisant find (interprétera mieux si la classe existe dans M et ne se fait pas être la dernière constante M - bien qu'il devrait rarement faire une différence mesurable):

M.constants.find {|c| M.const_get(c) == M::C } 

Edit: Puisque vous voulez en fait juste un résultat booléen, ce any? fait plus envoyer que find:

M.constants.any? {|c| M.const_get(c) == M::C } 
+0

Je pense Mc onstants.find {| c | M.const_get (c) == M :: C} fonctionne mieux. – johannes

+0

Bon point. Je vais l'ajouter à la réponse. – sepp2k

+0

Un bon début, mais ça ne marchera pas si M :: C n'existe pas du tout. –

2

sepp2k's answer ne fonctionnera pas si M::C n'est pas défini du tout, puisque Ruby lèvera un NameError dans ce bloc.

Essayez ceci:

M.constants.include?('C') 

Si vous craignez que vous avez une référence à M::C par un autre nom, comme ceci:

module M 
    class C 
    end 
end 

MY_M_C = M::C 

alors vous pouvez tester si MY_M_C est le même comme M de C comme ça:

M.constants.include?('C') ? MY_M_C == M.const_get(:C) : false 
+1

pourquoi ne pas utiliser 'M.const_defined? (: C)' à la place? – horseyguy

+0

Cela marchera aussi bien et fonctionnera au moins aussi bien que le mien. Joli. –

Questions connexes