dynamically create a class without a namespace

我只是一个虾纸丫 提交于 2019-12-03 21:48:45

Defining Browser (or ::Browser, to directly answer your question) will prevent you from calling your factory more than once.

I would recommend to use an anonymous class. No need for eval, btw, and you can define the class method to_s if you want to:

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

Change

class Browser < #{super_class}

to

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

Here's a small testsuite:

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!