开发者

Ruby: Dynamically defining classes based on user input

I'm creating a library in Ruby that allows the user to access an external API. That API can be accessed via either a SOAP or a REST API. I would like to support both.

I've started by defining the necessary objects in different modules. For example:

soap_connecton = Library::Soap::Connection.new(username, password)
response = soap_connection.create Library::Soap::LibraryObject.new(type, data, etc)
puts response.class # Library开发者_开发百科::Soap::Response

rest_connecton = Library::Rest::Connection.new(username, password)
response = rest_connection.create Library::Rest::LibraryObject.new(type, data, etc)
puts response.class # Library::Rest::Response

What I would like to do is allow the user to specify that they only wish to use one of the APIs, perhaps something like this:

Library::Modes.set_mode(Library::Modes::Rest)
rest_connection = Library::Connection.new(username, password)
response = rest_connection.create Library::LibraryObject.new(type, data, etc)
puts response.class # Library::Response

However, I have not yet discovered a way to dynamically set, for example, Library::Connection based on the input to Library::Modes.set_mode. What would be the best way to implement this functionality?


Murphy's law prevails; find an answer right after posting the question to Stack Overflow.

This code seems to have worked for me:

module Library
  class Modes
    Rest = 1
    Soap = 2

    def self.set_mode(mode)
      case mode
      when Rest
        Library.const_set "Connection", Class.new(Library::Rest::Connection)
        Library.const_set "LibraryObject", Class.new(Library::Rest::LibraryObject)
      when Soap
        Library.const_set "Connection", Class.new(Library::Soap::Connection)
        Library.const_set "LibraryObject", Class.new(Library::Soap::LibraryObject)
      else
        throw "#{mode.to_s} is not a valid Library::Mode"
      end
    end
  end
end

A quick test:

Library::Modes.set_mode(Library::Modes::Rest)
puts Library::Connection.class == Library::Rest::Connection.class # true
c = Library::Connection.new(username, password)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜