代码类和实例级别的模块方法中的代码重复

时间:2015-10-01 10:03:18

标签: ruby-on-rails ruby

我有Memoize模块,它提供了缓存类和实例方法的方法。

module Memoize
  def instance_memoize(*methods)
    memoizer = Module.new do
      methods.each do |method|
        define_method method do
          @_memoized_results ||= {}

          if @_memoized_results.include? method
            @_memoized_results[method]
          else
            @_memoized_results[method] = super()
          end
        end
      end
    end

    prepend memoizer
  end

  def class_memoize(*methods)
    methods.each do |method|
      define_singleton_method method do
        @_memoized_results ||= {}

        if @_memoized_results.include? method
          @_memoized_results[method]
        else
          @_memoized_results[method] = super()
        end
      end
    end
  end
end

这是我如何使用它的一个例子:

class Foo
  extend Memoize

  instance_memoize :instance_method1, :instance_method2
  class_memoize    :class_method1, :class_method2

  ...
end

请在此模块中建议如何避免代码重复。

1 个答案:

答案 0 :(得分:1)

可以定义lambda

λ = lambda do
  @_memoized_results ||= {}

  if @_memoized_results.include? method
    @_memoized_results[method]
  else
    @_memoized_results[method] = super()
  end
end

和。然后:

define_method method, &λ

请注意λ前面的&符号,它用于通知define_method它正在接收一个块,而不是常规参数。

我没有得到这种方法的失败,但这是一个防弹版本:

method_declaration = %Q{
  def %{method}
    @_memoized_results ||= {}

    if @_memoized_results.include? :%{method}
      @_memoized_results[:%{method}]
    else
      @_memoized_results[:%{method}] = super()
    end
  end
}

methods.each do |method|
  class_eval method_declaration % {method: method}
end