Memoize
memoizes function return values based on class name, method name, and arguments. This means that this only works for functions that use state / have side effects.
module Memoize
def memoize(definition)
self.send(:alias_method, "__original_#{definition}", definition)
define_method definition, Proc.new { |*args|
@__memo ||= {}
key = "#{self.class.name}##{definition}/#{args.hash}"
return @__memo[key] if @__memo.key?(key)
@__memo[key] = send("__original_#{definition}", *args)
}
end
end
Usage
class A
class B
extend Memoize
def heavy_calculation(a, b)
p "calling the original"
a * b
end
memoize :heavy_calculation
end
end
b = A::B.new
p b.heavy_calculation(4, 20)
# "calling the original"
# 80
p b.heavy_calculation(4, 20)
# 80
p b.heavy_calculation(2, 20)
# "calling the original"
# 40