我有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
请在此模块中建议如何避免代码重复。
答案 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