在watir-classic gem中,我们在Element类下有一个名为generate_ruby_code()的方法。我想修补它并修改一些东西。
我做的是:
require 'watir-classic'
module Watir
class Element
def generate_ruby_code(element, method_name, *args)
puts "Print this"
end
end
end
但是不是调用我的猴子补丁方法,而是每次都调用Element类中的原始generate_ruby_code,我不想发生这种情况。
请帮我解决这个问题。
答案 0 :(得分:2)
<强>问题强>
我假设您使用的是watir-classic v3.7.0或更早版本。
在这些版本中,执行require 'watir-classic'
不会立即加载所有类。在创建浏览器实例之前,不会加载某些类,包括Watir :: Element。
这意味着:
# Does not create Watir::Element#generate_ruby_code yet
require 'watir-classic'
# You create a Watir::Element#generate_ruby_code method
module Watir
class Element
def generate_ruby_code(element, method_name, *args)
puts "Print this"
end
end
end
# Watir loads the Watir::Element#generate_ruby_code, which overrides yours
browser = Watir::Browser.new
我的理解是,这是因为以前支持多种浏览器的tp watir-classic - 即FireWatir和SafariWatir。根据使用的浏览器自动加载各种类。
解决方案1 - 升级到v4.0或更高版本
最简单的解决方案是将您的watir-classic升级到v4.0或更高版本(当前最新版本为4.0.1)。
此版本中删除了自动加载功能,这意味着您的代码现在可以按原样运行。
解决方案2 - 首先初始化浏览器
如果无法升级,则需要在猴子修补前手动强制自动加载。您可以通过简单地引用常量来执行此操作:
Watir::IE
在需要watir-classic和猴子修补之前,只需在某些时候包括它。
require 'watir-classic'
Watir::IE # this will load the code
module Watir
class Element
def generate_ruby_code(element, method_name, *args)
puts "Print this"
end
end
end
browser = Watir::Browser.new
browser.goto 'www.google.ca'
browser.link.click_no_wait
#=> "Print this"
答案 1 :(得分:0)
看,我不知道你的情况究竟发生了什么,但是你可以安全地排除Ruby故障。以下是一些提示:
# Assuming that your element of class Watir::Element is stored in variable x:
x.method( :generate_ruby_code ).owner # will give you the owning module
x.method( :generate_ruby_code ).source_location # will give you the place where the method is,
# that is going to be used when you send x the message :generate_ruby_code
x.class # will confirm that your object indeed is what you think it is
x.singleton_class.ancestors # will give you the full method lookup chain for x
有了这个,你应该有能力发现为什么你对x的行为的期望得不到满足。