2010-09-27 5 views
5

Je suis nouveau à Ruby, et un petit bijou que je fais d'interagir avec une API JSONRPC et essentiellement tous les appels et les réponses sont assez semblables, qui peuvent être traitées chaque appel API avec une fonction, comme:Est-ce un abus de métaprogrammation rubis?

Module::api_command('APINamespace.NamespaceMethod')

mais je voudrais aussi (pour des raisons de commodité) être en mesure de le faire:

Module::APINamespace.NamespaceMethod

y at-il raison de ne pas le faire en utilisant Module.const_missing pour retourner une classe fictive qui a un method_missing qui permettra passin g l'appel de Module::APINamespace.NamespaceMethod à Module::api_command('APINamespace.NamespaceMethod')

Y a-t-il une façon plus élégante ou civilisée de faire cela?

+0

bien? Est-ce que ma réponse a fait ce que tu voulais? Je n'ai toujours pas eu de réponse de votre part .. – horseyguy

Répondre

2

Oui, je suis désolé, mais dans mon esprit ce hack est ridicule. :)

D'abord, je suppose que votre méthode api_command est en fait des méthodes sur invoquaient le module APINamespace, comme le laisse entendre cette ligne: Module::api_command('APINamespace.NamespaceMethod')

Compte tenu de ce qui précède, pourquoi ne pas simplement définir une constante égale à APINamespace dans votre module?

MyModule::APINamespace = ::APINamespace 
MyModule::APINamespace.NamespaceMethod() 

MISE À JOUR:

Je ne suis toujours pas tout à fait comprendre votre situation, mais peut-être ceci:

module MyModule 
    def self.const_missing(c) 
     Object.const_get(c) 
    end 
end 

Maintenant, vous pouvez appeler tout haut niveau constant comme il a été défini sur votre module; dire qu'il y avait un module appelé StrangeAPI au plus haut niveau, si vous utilisez le hack ci-dessus, vous pouvez maintenant invoquer ses méthodes comme suit:

MyModule::StrangeAPI.Blah() 

Est-ce que vous voulez?

+0

Je me suis dit que c'était une bonne façon de faire, et c'est pourquoi j'ai posté la question: p. Je ne suis pas sûr de comprendre l'affectation = :: APINamespace, que se passe-t-il? – re5et

+0

@ re5et, si j'ai bien compris ce que vous faites correctement - il existe en fait un module appelé 'APINamespace' qui contient les méthodes que vous voulez appeler ... mais vous les appelez actuellement via' MyModule.api_command() '. Ma solution lie simplement une constante appelée 'MyModule :: APINamespace' à la constante globale' APINamespace' ... vous permettant d'invoquer directement les méthodes 'ApiNamespace' depuis votre module en allant' MyModule :: APINamespace.NameSpaceMethod() ' – horseyguy

+0

le problème est qu'il y a un tas d'espaces de noms, qui ont tous leurs propres méthodes. Je me demandais s'il y avait quelque chose que je pouvais faire autrement que de les définir chacun comme une constante dans le module. – re5et