Module: Memoizable
- Defined in:
- lib/standard/facets/memoizable.rb
Overview
Memoization is an optimization technique used primarily to speed up programs by having function calls avoid repeating the calculation of results for previously-processed inputs.
When you “memoize” a method/function using Memoizable its results are cached so that later calls return results from the cache instead of recalculating them.
class T
include Memoizable
def initialize(a)
@a = a
end
def a
"#{@a ^ 3 + 4}"
end
memoize :a
end
t = T.new(10)
(t.a.__id__ == t.a.__id__) #=> true
This method can also be used at the instance level to cache singleton (qua class) methods by including it in the singleton class.
– TODO: It would be very cool if Memoizable could set-up default parameters via #[] method, e.g. ‘include Memoizable`. ++
Defined Under Namespace
Modules: Copy
Class Method Summary collapse
Instance Method Summary collapse
-
#memoize(*method_names) ⇒ Object
Directive for making your functions faster by trading space for time.
-
#rememoize(*method_names) ⇒ Object
Remove the memoized value from the memoization cache.
- #unmemoize(*method_names) ⇒ Object
Class Method Details
.append_features(base) ⇒ Object
44 45 46 |
# File 'lib/standard/facets/memoizable.rb', line 44 def self.append_features(base) Module == base ? super(base) : base.extend(self) end |
.cache ⇒ Object
39 40 41 |
# File 'lib/standard/facets/memoizable.rb', line 39 def self.cache @cache end |
Instance Method Details
#memoize(*method_names) ⇒ Object
Directive for making your functions faster by trading space for time. When you “memoize” a method/function using #memoize its results are cached so that later calls with the same arguments return results from the cache instead of recalculating them.
The #memoize method also handles a few options to alter behavior of the memoization:
:class => true cache per-class not per-object
:freeze => true freeze the memoized return values
:arguments => false do not index cache by arguments
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/standard/facets/memoizable.rb', line 60 def memoize(*method_names) = Hash === method_names.last ? method_names.pop : {} [:arguments] = true if [:arguments].nil? # default to true ref = [:class] ? 'self.class.name' : 'self' frz = [:freeze] ? '.freeze' : '' arg = [:arguments] ? '[__a__, block_given?]' : 'nil' code = "" method_names.each do |m| code << <<-code alias_method '#{ m }:memo', '#{ m }' private '#{ m }:memo' def #{ m }(*__a__,&__b__) c = Memoizable.cache[#{ref}][:'#{ m }'] k = #{arg} if c.has_key?(k) c[k] else c[k] = __send__('#{ m }:memo',*__a__,&__b__)#{frz} end end code end module_eval(code) end |
#rememoize(*method_names) ⇒ Object
Remove the memoized value from the memoization cache. The next time a memoized methos is called if will be remomoized.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/standard/facets/memoizable.rb', line 91 def rememoize(*method_names) if Memoizable.cache[self] if method_names.empty? Memoizable.cache.delete(self) else method_names.each do |m| Memoizable.cache[self].delete(m.to_sym) end end end if Memoizable.cache[self.class.name] if method_names.empty? Memoizable.cache.delete(self.class.name) else method_names.each do |m| Memoizable.cache[self.class.name].delete(m.to_sym) end end end end |
#unmemoize(*method_names) ⇒ Object
113 114 115 116 117 118 |
# File 'lib/standard/facets/memoizable.rb', line 113 def unmemoize(*method_names) rememoize(*method_names) method_names.each do |m| alias_method name, "#{ m }:memo" end end |