2015-12-15 3 views
5

Я хочу переопределить метод 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 

Как я могу назвать исходный метод методом переопределения?

ответ

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

Selenium::WebDriver.singleton_class.prepend(SeleniumWebDriverExtension) 
+1

Умный, спасибо! Теперь мы используем это для изменения «NewRelic :: Agent :: Hostname.get» с резервным супер. – Raffael

4

Когда вы используете self внутри модуля, как это:

def self.for(browser, *args) 

end 

он объявлен как module function, а не метод экземпляра класса, который будет включать в себя этот модуль. Это означает, что это не будет отображаться в включенных классах, когда модуль будет смешан в другой класс.

Это похоже на письма:

def SeleniumWebDriverExtension::for 
end 

Так что, если вы хотите вызвать super внутри модуля, объявить его как простой instance method как принятый ответ предложил. Просто хотел очистить вас от рассуждений позади этого.

Btw SeleniumWebDriverExtension.ancestors, чтобы быть ясным в иерархии наследования.