我正在尝试使用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
答案 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