How to override class methods
Asked Answered
R

2

7

I want to override the method Selenium::WebDriver.for. This is what I tried:

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)

But I got error when Selenium::Webdriver.for(:phantomjs) is called.

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

How can I call the original method from the overriding method?

Romelda answered 15/12, 2015 at 4:55 Comment(0)
T
10
module SeleniumWebDriverExtension
  def for(browser, *args)
    ...
  end
end

Selenium::WebDriver.singleton_class.prepend(SeleniumWebDriverExtension)
Typeset answered 15/12, 2015 at 5:21 Comment(1)
Clever, thanks! We now use this to amend NewRelic::Agent::Hostname.get with a fallback to super.Footy
P
4

When to you use self inside a module like this:

def self.for(browser, *args)

end

it is declared as a module function, not an instance method on the class that will include this module. What this means is that won't appear on included classes when the module is mixed into another class.

It is similar to writing:

 def SeleniumWebDriverExtension::for
 end

So if you want to call super from within the module, declare it as a simple instance method like the accepted answer has suggested. Just wanted to clear you on the reasoning behind this.

Btw SeleniumWebDriverExtension.ancestors to be clear on the inheritance hierarchy.

Procurable answered 15/12, 2015 at 7:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.