首页 > 解决方案 > 多个类的 DRY-ing 方法救援

问题描述

我正在尝试做一些在我看来非常基本的事情,但我想不出办法让它变干。

这是我最初的代码:

我的第一个工人

class WorkerOne < BaseWorker
  def perform
    # do stuff
  rescue *exceptions_to_rescue_with_error => error
    job_error(error, try_later: false)
  rescue *exceptions_to_rescue_with_error_and_try_later => error
    job_error(error, try_later: true)
  rescue *exceptions_to_rescue_with_warning => message
    job_warning(message, try_later: false)
  end
end

我的第二个工人

class WorkerTwo < BaseWorker
  def perform
    # do stuff
  rescue *exceptions_to_rescue_with_error => error
    job_error(error, try_later: false)
  rescue *exceptions_to_rescue_with_error_and_try_later => error
    job_error(error, try_later: true)
  rescue *exceptions_to_rescue_with_warning => message
    job_warning(message, try_later: false)
  end
end

父类

class BaseWorker
  def exceptions_to_rescue_with_error
    [
      Exceptions::SomeOtherError,
      ActiveRecord::RecordNotFound
    ]
  end

  def exceptions_to_rescue_with_error_and_try_later
    [
      Exceptions::SomeError1,
      Exceptions::SomeError2,
    ]
  end

  def exceptions_to_rescue_with_warning
    [
      Exceptions::SomeWarning
    ]
  end
end

这是我添加到 BaseWorker 以使其工作的方法:


  def self.with_job_rescue_for_perfom
    define_method(:perform) do |*args, &block|
      self.perform(*args, &block)
      rescue *exceptions_to_rescue_with_error => error
        job_error(error, try_later: false)
      rescue *exceptions_to_rescue_with_error_to_try_later => error
        job_error(error, try_later: true)
      rescue *exceptions_to_rescue_with_warning => message
        job_warning(message, try_later: false)
    end
  end
end

我被困在那里,我不知道下一步该往哪里看。似乎这里使用的方法对我不起作用,因为我没有使用模块。

任何想法?

标签: rubymetaprogramming

解决方案


我会做这样的事情:

class BaseWorker
  def exceptions_to_rescue_with_error
    [
      Exceptions::SomeOtherError,
      ActiveRecord::RecordNotFound
    ]
  end

  def exceptions_to_rescue_with_error_and_try_later
    [
      Exceptions::SomeError1,
      Exceptions::SomeError2,
    ]
  end

  def exceptions_to_rescue_with_warning
    [
      Exceptions::SomeWarning
    ]
  end

  def perform
    do_stuff
  rescue *exceptions_to_rescue_with_error => error
    job_error(error, try_later: false)
  rescue *exceptions_to_rescue_with_error_and_try_later => error
    job_error(error, try_later: true)
  rescue *exceptions_to_rescue_with_warning => message
    job_warning(message, try_later: false)
  end
end

class WorkerOne < BaseWorker
  def do_stuff
    # do stuff
  end
end

class WorkerTwo < BaseWorker
  def do_stuff
    # do stuff
  end
end

推荐阅读