Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this ruby metaprogramming abuse?

I am new to Ruby, and have a gem that I am making to interact with a JSONRPC API and basically all calls and responses are similar enough, that every API call can be handled with one function, like:

Module::api_command('APINamespace.NamespaceMethod')

but I would like to also (for convenience sake) be able to do:

Module::APINamespace.NamespaceMethod

Is there any reason not to do this by using Module.const_missing to return a dummy class that has a method_missing which will allow passing the call from Module::APINamespace.NamespaceMethod to Module::api_command('APINamespace.NamespaceMethod')

Is there a more elegant or civilized way to do this?

like image 514
re5et Avatar asked Sep 27 '10 17:09

re5et


1 Answers

Yes, I'm sorry, but to my mind that hack is ridiculous. :)

First of all, i'm assuming that your api_command method is actually invoking methods on the APINamespace module, as implied by this line: Module::api_command('APINamespace.NamespaceMethod')

Given the above, why not just set a constant equal to APINamespace in your module?

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

UPDATE:

I'm still not entirely understanding your situation, but perhaps this:

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

Now you can invoke any top-level constant as if it was defined on your module; say there was a module called StrangeAPI at top-level, if you use the hack above, you can now invoke its methods as follows:

MyModule::StrangeAPI.Blah()

Is this what you want?

like image 187
horseyguy Avatar answered Nov 12 '22 04:11

horseyguy