简体   繁体   中英

Code duplication in a module methods of class and instance levels

I have Memoize module, that provides methods for caching of class and instance methods.

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

This is an example of how I use it:

class Foo
  extend Memoize

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

  ...
end

Please advice how to avoid code duplication in this module.

One might define a lambda :

λ = lambda do
  @_memoized_results ||= {}

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

And. then:

define_method method, &λ

Please be aware of an ampersand in front of λ , it is used to notice define_method about it's receiving a block, rather than a regular argument.


I did not get what failed with this approach on your side, but here is a bullet-proof version:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM