首页 > 解决方案 > 如何将块转发到生成方法的方法

问题描述

在我当前的项目中,我在某些课程中有以下重复模式:

class MyClass

  def method1(pars1, ...)
    preamble

    # implementation method1

    rescue StandardError => e
      recovery
  end

  def method2(pars2, ...)
    preamble

    # implementation method2

    rescue StandardError => e
      recovery
  end

  # more methods with the same pattern
end

所以,我一直在思考如何干燥这种重复的模式。我的目标是拥有这样的东西:

class MyClass

  define_operation :method1, pars1, ... do
    # implementation method1
  end

  define_operation :method2, pars2, ... do
    # implementation method2
  end

  # more methods with the same pattern but generated with define_wrapper_method
  end

我试图实现一种元生成器,但在转发接收生成器的块时遇到了问题。这或多或少是我尝试过的:

def define_operation(op_name, *pars, &block)
  define_method(op_name.to_s) do |*pars|
    preamble
    yield # how can I do here for getting the block? <-----
    rescue StandardError => e
      recovery
  end
end

不幸的是,我找不到转发block到该方法的define_method方法。此外,数量可变的参数很可能以define_method错误的方式传递给。

我将不胜感激任何线索,帮助,建议。

标签: ruby-on-railsrubymetaprogramming

解决方案


您不需要元编程来实现这一点。只需添加一个包装通用逻辑的新方法,如下所示:

class MyClass

  def method1(param1)
    run_with_recovery(param1) do |param1|
       # implementation method1
    end
  end

  def method2(param1, param2)
    run_with_recovery(param1, param2) do |param1, param2|
       # implementation method2
    end
  end

  private

  def run_with_recovery(*params)
    preamble
    yield(*params)
    rescue StandardError => e
      recovery
  end
end

在这里测试它:http ://rubyfiddle.com/riddles/4b6e2


如果您真的想做元编程,这将起作用:

class MyClass

  def self.define_operation(op_name)
    define_method(op_name.to_s) do |*args|
      begin
        puts "preamble"
        yield(args)
      rescue StandardError => e
        puts "recovery"
      end
    end
  end

  define_operation :method1 do |param1|
    puts param1
  end

  define_operation :method2 do |param1, param2|
    puts param1
    puts param2
  end

end

MyClass.new.method1("hi")
MyClass.new.method2("hi", "there")

在这里测试这个:http ://rubyfiddle.com/riddles/81b9d/2


推荐阅读