[英]Ruby execute code in class getting inherited to
I'm trying to be able to have a global exception capture where I can add extra information when an error happens.我正在尝试能够进行全局异常捕获,以便在发生错误时添加额外信息。 I have two classes, "crawler" and "amazon".我有两个班级,“爬虫”和“亚马逊”。 What I want to do is be able to call "crawl", execute a function in amazon, and use the exception handling in the crawl function.我想要做的是能够调用“抓取”,在亚马逊中执行 function,并在抓取 function 中使用异常处理。
Here are the two classes I have:这是我的两个课程:
require 'mechanize'
class Crawler
Mechanize.html_parser = Nokogiri::HTML
def initialize
@agent = Mechanize.new
end
def crawl
puts "crawling"
begin
#execute code in Amazon class here?
rescue Exception => e
puts "Exception: #{e.message}"
puts "On url: #{@current_url}"
puts e.backtrace
end
end
def get(url)
@current_url = url
@agent.get(url)
end
end
class Amazon < Crawler
#some code with errors
def stuff
page = get("http://www.amazon.com")
puts page.parser.xpath("//asldkfjasdlkj").first['href']
end
end
a = Amazon.new
a.crawl
Is there a way I can call "stuff" inside of "crawl" so I can use that exception handling over the entire stuff function?有没有一种方法可以在“爬网”中调用“东西”,这样我就可以对整个东西 function 使用该异常处理? Is there a better way to accomplish this?有没有更好的方法来完成这个?
EDIT: This is when I ended up doing编辑:这是我结束的时候
require 'mechanize'
class Crawler
Mechanize.html_parser = Nokogiri::HTML
def initialize
@agent = Mechanize.new
end
def crawl
yield
rescue Exception => e
puts "Exception: #{e.message}"
puts "On url: #{@current_url}"
puts e.backtrace
end
def get(url)
@current_url = url
@agent.get(url)
end
end
c = Crawler.new
c.crawl do
page = c.get("http://www.amazon.com")
puts page.parser.xpath("//asldkfjasdlkj").first['href']
end
I managed to get the desired functionality with "super" and a placeholder function. Is there still a better way to do this?我设法通过“super”和占位符 function 获得了所需的功能。还有更好的方法吗?
require 'mechanize'
class Crawler
Mechanize.html_parser = Nokogiri::HTML
def initialize
@agent = Mechanize.new
end
def stuff
end
def crawl
stuff
rescue Exception => e
puts "Exception: #{e.message}"
puts "On url: #{@current_url}"
puts e.backtrace
end
def get(url)
@current_url = url
@agent.get(url)
end
end
class Amazon < Crawler
#some code with errors
def stuff
super
page = get("http://www.amazon.com")
puts page.parser.xpath("//asldkfjasdlkj").first['href']
end
end
a = Amazon.new
a.crawl
You could have crawl accept a code block:你可以让 crawl 接受一个代码块:
def crawl
begin
yield
rescue Exception => e
# handle exceptoin
end
end
def stuff
crawl do
# implementation of stuff
end
end
I'm not crazy about having a method with no body.我对没有身体的方法并不疯狂。 A code block might make more sense here.代码块在这里可能更有意义。 May also eliminate the need for subclassing depending on what you want to do.还可以根据您想要执行的操作消除子类化的需要。
If you want it another way, take a look at "strategy" design patten:如果您想要另一种方式,请查看“策略”设计模式:
# test_mach.rb
require 'rubygems'
require 'mechanize'
# this is the context class,which calls the different strategy implementation
class Crawler
def initialize(some_website_strategy)
@strategy = some_website_strategy
end
def crawl
begin
@strategy.crawl
#execute code in Amazon class here?
rescue Exception => e
puts "==== starts this exception comes from Parent Class"
puts e.backtrace
puts "==== ends this exception comes from Parent Class"
end
end
end
# strategy class for Amazon
class Amazon
def crawl
puts "now crawling amazon"
raise "oh ... some errors when crawling amazon"
end
end
# strategy class for taobao.com
class Taobao
def crawl
puts "now crawling taobao"
raise "oh ... some errors when crawling taobao"
end
end
then run this code:然后运行这段代码:
amazon = Crawler.new(Amazon.new)
amazon.crawl
taobao = Crawler.new(Taobao.new)
taobao.crawl
result:结果:
now crawling amazon
==== starts this exception comes from Parent Class
test_mach.rb:27:in `crawl'
test_mach.rb:13:in `crawl'
test_mach.rb:38
==== ends this exception comes from Parent Class
now crawling taobao
==== starts this exception comes from Parent Class
test_mach.rb:34:in `crawl'
test_mach.rb:13:in `crawl'
test_mach.rb:40
==== ends this exception comes from Parent Class
BTW.顺便提一句。 for your implementation, basically I did the same way with you.对于你的实施,基本上我对你做了同样的事情。 except除了
# my implementation
class Crawler
def stuff
raise "abstract method called"
end
end
If you want it another way, take a look at "around alias" (<< metaprogramming ruby>>, page 155 ).如果您想要另一种方式,请查看“around alias”(<< metaprogramming ruby>>,第 155 页)。 However I think "around alias" is the revert case from strategy.但是我认为“围绕别名”是策略的还原案例。
( I mean, ( 我是说,
err... hope I didn't make you confused ^_^ )呃...希望我没有让你感到困惑^_^)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.