Je fais des métaprogramming à Ruby et je dois générer de manière dynamique une classe de frère de soeur à l'intérieur d'un module. Ce faisant, je veux appeler const_set sur le module, mais je ne sais pas quel module constant à appeler cela jusqu'à l'exécution. Exemple:
Connectes de classes p> Je veux pouvoir appeler une fonction comme celle-ci (simplifiée ici): p> Foo::Quox::GeneratedClassName
4 Réponses :
obtenu. ActiveSupport a cette extension de rubis, numéro de module # C'est assez bon pour mon usage. P>
J'ai trouvé une autre façon qui peut vous aider au cas où vous ne voulez pas utiliser ActiveSupport pour cela uniquement. Si vous utilisez des rails de toute façon, ce n'est pas une préoccupation.
J'ai accepté ma réponse, car cela faisait exactement ce que je voulais et j'utilise ActiveSupport, mais j'ai suscité la réponse de Michael depuis qu'il semble également correct lorsqu'il n'utilise pas ActiveSupport
Cela devrait vous obtenir sur la bonne voie:
module Foo module Bar class Baz def initialize @nesting = Module.nesting end def enclosing_module @nesting.last end end end end puts Foo::Bar::Baz.new.enclosing_module #=> Foo
Cela ne fonctionne pas (ou fait quelque chose d'éventuellement inattendu) avec héritage - si vous créez une sous-classe corge :: qux
corge :: qux.new .Close_Module code> sera toujours
foo code>.
Vrai. Je n'ai certes pas été testé avec héritage, c'est pourquoi j'ai dit "devrait vous mettre sur la bonne voie", pas "est exactement ce dont vous avez besoin". Merci pour les commentaires cependant!
Dans les rails Vous pouvez utiliser une combinaison de Deconstantize et Constantize .
self.class.name.deconstantize.constantize
Si quiconque cherche une version de rubis pur:
Les deux seules façons que je connaisse, ce serait la façon dont vous décrivez en bas et y compris une fonction
get_module code> dans chaque classe. Mais, on se sent comme là Devrait I> un moyen de le faire. Garder un oeil sur celui-ci ...