【问题标题】:How to override class methods如何覆盖类方法
【发布时间】:2015-12-15 04:55:12
【问题描述】:

我想重写方法Selenium::WebDriver.for。这是我尝试过的:

module SeleniumWebDriverExtension
  def self.for(browser, *args)
    if browser != :phantomjs
      super(browser, *args)
    else
      options = {
          "phantomjs.cli.args" => ["--ssl-protocol=tlsv1"]
      }
      capabilities = Selenium::WebDriver::Remote::Capabilities.phantomjs(options)
      super(browser, desired_capabilities: capabilities)
    end
  end
end

Selenium::WebDriver.prepend(SeleniumWebDriverExtension)

但在调用Selenium::Webdriver.for(:phantomjs) 时出现错误。

NoMethodError: super: no superclass method `for' for Selenium::WebDriver::Driver:Class

如何从覆盖方法调用原始方法?

【问题讨论】:

    标签: ruby overriding class-method prepend


    【解决方案1】:
    module SeleniumWebDriverExtension
      def for(browser, *args)
        ...
      end
    end
    
    Selenium::WebDriver.singleton_class.prepend(SeleniumWebDriverExtension)
    

    【讨论】:

    • 聪明,谢谢!我们现在使用它来修改 NewRelic::Agent::Hostname.get 并回退到 super。
    【解决方案2】:

    何时在这样的模块中使用self

    def self.for(browser, *args)
    
    end
    

    它被声明为module function,而不是包含此模块的类的实例方法。这意味着当模块混合到另一个类中时,它不会出现在包含的类中。

    类似写法:

     def SeleniumWebDriverExtension::for
     end
    

    因此,如果您想从模块中调用super,请将其声明为简单的instance method,就像接受的答案所建议的那样。只是想澄清一下这背后的原因。

    顺便说一句 SeleniumWebDriverExtension.ancestors 以明确继承层次结构。

    【讨论】:

      猜你喜欢
      • 2023-03-15
      • 2011-03-05
      • 2021-01-14
      • 2014-03-17
      • 2018-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      相关资源
      最近更新 更多