Ruby:根据用户输入动态定义类

时间:2011-02-25 23:42:50

标签: ruby class dynamic

我正在Ruby中创建一个允许用户访问外部API的库。可以通过SOAP或REST API访问该API。我想支持两者。

我开始在不同的模块中定义必要的对象。例如:

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

我想要做的是允许用户指定他们只希望使用其中一个API,可能是这样的:

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

但是,我还没有找到一种根据Library::Connection的输入动态设置的方法,例如Library::Modes.set_mode。实现此功能的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

墨菲的法律占上风;在将问题发布到Stack Overflow之后立即找到答案。

这段代码似乎对我有用:

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

快速测试:

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