如何覆盖类方法

时间:2015-12-15 04:55:12

标签: ruby override class-method prepend

我想覆盖方法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

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

2 个答案:

答案 0 :(得分:9)

module SeleniumWebDriverExtension
  def for(browser, *args)
    ...
  end
end

Selenium::WebDriver.singleton_class.prepend(SeleniumWebDriverExtension)

答案 1 :(得分:4)

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

def self.for(browser, *args)

end

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

类似于写作:

 def SeleniumWebDriverExtension::for
 end

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

要在继承层次结构中明确SeleniumWebDriverExtension.ancestors