动态创建没有命名空间的类

时间:2009-12-22 09:39:48

标签: ruby metaprogramming eval

我正在尝试使用eval方法动态创建一个类。除了一个小问题外它工作得很好。正如我的代码所示,我在BrowserFactory类中创建了Browser类。当我这样做时,Browser类有一个添加的BrowserFactory命名空间。无论如何从没有附加BrowserFactory名称空间的字符串中评估Browser类?


class BrowserFactory
  def self.create_browser(browser)
    super_class = nil
    case browser
    when 'IE'
      require 'watir'
      super_class = 'Watir::IE'
    when 'celerity'
      require 'celerity'
      super_class = 'Celerity::Browser'
    end

    raise StandardError.new("Browser '#{browser}' is not currentlys supported") if super_class.nil?

    eval <<EOS
class Browser < #{super_class}
include Singleton
include BrowserModification
end
EOS

    return Browser.instance
  end

end

3 个答案:

答案 0 :(得分:3)

定义浏览器(或::浏览器,直接回答您的问题)将阻止您多次致电您的工厂。

我建议使用匿名类。不需要eval,btw,如果你想要,你可以定义类方法to_s:

class BrowserFactory
  def self.create_browser(browser)
    super_class = case browser
    when 'IE'
      require 'watir'
      Watir::IE
    when 'celerity'
      require 'celerity'
      Celerity::Browser
    else
      raise StandardError.new("Browser '#{browser}' is not currentlys supported")
    end

    klass = Class.new(super_class) do
      include Singleton
      include BrowserModification
      def self.to_s
        "Modified#{superclass}"
      end
    end
    klass.instance
  end
end

答案 1 :(得分:2)

更改

class Browser < #{super_class}

class ::Browser < #{super_class}

答案 2 :(得分:0)

def BrowserFactory(browser)
  case browser
  when 'IE'
    require 'watir'
    Watir::IE
  when 'celerity'
    require 'celerity'
    Celerity::Browser
  else
    raise ArgumentError, "Browser '#{browser}' is not currently supported"
  end.new.extend(BrowserModification)
end

这是一个小型测试套件:

module Watir; class IE; def to_s; 'IE' end end end
module Celerity; class Browser; def to_s; 'Celerity' end end end

module BrowserModification; def to_s; "Modified#{super}" end end

require 'test/unit'
class TestBrowserFactory < Test::Unit::TestCase
  def test_that_celerity_responds_as_modified_celerity
    assert_equal 'ModifiedCelerity', BrowserFactory('celerity').to_s
  end
  def test_that_internet_explorer_responds_as_modified_internet_explorer
    assert_equal 'ModifiedIE', BrowserFactory('IE').to_s
  end
  def test_that_an_invalid_browser_raises_an_exception
    assert_raise ArgumentError do BrowserFactory('xyz') end
  end
end