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

我试图使用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 

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

我建议使用匿名类。 不需要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 

更改

 class Browser < #{super_class} 

 class ::Browser < #{super_class} 
 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