Again alias_method_chain. Simple and elegant (I think) way to add retry functionality to curl based screen scraper

require 'curb'
module Extend::Curl
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    #optional parameters

    def with_curl_retry(method_name, opts={})
      opts.reverse_merge!(:try => 2, :sleep => 2, :error => StandardError)
      error_attribute_name = "#{method_name}_with_curl_retry_error"
      write_inheritable_attribute(error_attribute_name, opts[:error])
      src_code= <<-CODE
        def #{method_name.to_s}_with_curl_retry(*args)
          num_tries = #{opts[:try]}
          begin
            return #{method_name.to_s}_without_curl_retry(*args)
          rescue Curl::Err::CurlError => e
            num_tries -= 1
            retry if num_tries > 0 && sleep(#{opts[:sleep]})
            raise self.class.read_inheritable_attribute("#{error_attribute_name}")
          end
        end
        alias_method_chain :#{method_name.to_s}, :curl_retry unless method_defined?(:#{method_name.to_s}_without_curl_retry)
      CODE
      class_eval src_code
    end
  end
end

and then in your code

class SuperScreenScraper
  def do_some_scraping(a,b,c)
    ...
  end

  include Extend::Curl
  #try 3 times and sleep 1 second in between tries
  with_curl_retry :do_some_scraping, :sleep => 1, :try => 3
end