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

发布于 2024-08-16 06:57:18 字数 718 浏览 5 评论 0原文

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

I am trying to dynamically create a class using the eval method. It is working fine except for one small problem. As my code shows I am creating the Browser class inside the BrowserFactory class. When I do this the Browser class has an added namespace of BrowserFactory. Is there anyway to evaluate the Browser class from a string without the BrowserFactory namespace being attached?


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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

掐死时间 2024-08-23 06:57:18

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

我建议使用匿名类。不需要 eval,顺便说一句,如果您愿意,您可以定义类方法 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

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
那伤。 2024-08-23 06:57:18

更改

class Browser < #{super_class}

class ::Browser < #{super_class}

Change

class Browser < #{super_class}

to

class ::Browser < #{super_class}
暖风昔人 2024-08-23 06:57:18
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
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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文