1

エラーが発生したときに追加情報を追加できるグローバルな例外キャプチャを使用できるようにしようとしています。「クローラー」と「アマゾン」の2つのクラスがあります。私がやりたいことは、「クロール」を呼び出して、Amazon で関数を実行し、クロール関数で例外処理を使用できるようにすることです。

ここに私が持っている2つのクラスがあります:

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

「クロール」内で「スタッフ」を呼び出して、スタッフ関数全体でその例外処理を使用できる方法はありますか? これを達成するためのより良い方法はありますか?

編集:これは私がやったときです

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
4

3 に答える 3

0

「スーパー」とプレースホルダー機能を使用して、目的の機能を取得することができました。これを行うためのより良い方法はまだありますか?

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
于 2012-04-06T22:53:10.507 に答える
0

別の方法が必要な場合は、「戦略」設計パターンをご覧ください。

# 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

次に、次のコードを実行します。

amazon = Crawler.new(Amazon.new)
amazon.crawl
taobao = Crawler.new(Taobao.new)
taobao.crawl

結果:

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

ところで。あなたの実装のために、基本的に私はあなたと同じようにしました。を除外する

# my implementation
class Crawler
  def stuff
    raise "abstract method called"
  end
end 

別の方法が必要な場合は、「エイリアスの周り」(<< metaprogramming ruby​​>>, page 155 ) を参照してください。ただし、「エイリアスの周り」は戦略からの復帰ケースだと思います。

( つまり、

  • 戦略パターンでは、最初に「コンテキスト」クラスを実装し、次に「戦略」クラスを実装する必要があります。
  • しかし、「エイリアスの周り」の呪文では、まず「戦略」を実装する必要があり、次に「戦略」を「エイリアスの周り」にする新しいクラスを作成します...

うーん...私があなたを混乱させなかったらいいのに^_^ )

于 2012-04-07T00:21:36.800 に答える
0

クロールでコード ブロックを受け入れることができます。

def crawl
  begin
    yield
  rescue Exception => e
    # handle exceptoin
  end
end

def stuff
  crawl do
    # implementation of stuff
  end
end

私はボディのないメソッドを持つことに夢中ではありません。ここでは、コード ブロックの方が理にかなっています。やりたいことに応じて、サブクラス化の必要性をなくすこともできます。

于 2012-04-06T23:24:53.700 に答える