Module: ContextualMemery
- Defined in:
- lib/contextual_memery.rb,
lib/contextual_memery/version.rb,
sig/contextual_memery.rbs
Overview
Mix ContextualMemery into a class to gain a memoized method that turns on
Memery memoization for the duration of a block only, e.g.
class Thing
include ContextualMemery
def banana_time
...
end
end
instance = Thing.new
instance.memoized(:banana_time) do
instance.banana_time # computed
instance.banana_time # cached
end
instance.banana_time # computed again, cache is gone
include-ing this module also extends the including class with it, so the
same memoized method is available on the class itself, letting you scope
memoization to class (singleton) methods too:
Thing.memoized(:take_back) do
Thing.take_back
Thing.take_back
end
Defined Under Namespace
Classes: Error
Constant Summary collapse
- THREAD_KEY =
Thread-local nesting depth per memoized target (a singleton class), so that nested #memoized calls on the same object don't clear the cache out from under an outer, still-active block.
:contextual_memery_depths- EXCLUDED_METHOD_NAMES =
Methods we never want swept up by the implicit "memoize everything" mode.
%i[memoized initialize].freeze
- VERSION =
"0.1.0"
Class Method Summary collapse
- .active?(target) ⇒ Boolean
- .enter(target) ⇒ Object
- .included(base) ⇒ Object
-
.leave(target) ⇒ Object
Returns true when this call closed the outermost #memoized block for
target, i.e.
Instance Method Summary collapse
-
#memoized(*method_names) ⇒ Object
Turns on memoization for
method_names(or every method defined directly on the receiver when none are given, or:allis given) for the duration of the block.
Class Method Details
.active?(target) ⇒ Boolean
91 92 93 |
# File 'lib/contextual_memery.rb', line 91 def active?(target) depths.fetch(target, 0) > 0 end |
.enter(target) ⇒ Object
95 96 97 |
# File 'lib/contextual_memery.rb', line 95 def enter(target) depths[target] = depths.fetch(target, 0) + 1 end |
.included(base) ⇒ Object
43 44 45 46 |
# File 'lib/contextual_memery.rb', line 43 def self.included(base) super base.extend(self) end |
.leave(target) ⇒ Object
Returns true when this call closed the outermost #memoized block for
target, i.e. it's now safe to clear its memoized cache.
101 102 103 104 105 106 107 108 109 |
# File 'lib/contextual_memery.rb', line 101 def leave(target) depths[target] -= 1 if depths[target] <= 0 depths.delete(target) true else false end end |
Instance Method Details
#memoized(*method_names) ⇒ Object
Turns on memoization for method_names (or every method defined
directly on the receiver when none are given, or :all is given) for the
duration of the block. Works the same whether called on an instance or on
a class/module.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/contextual_memery.rb', line 52 def memoized(*method_names) raise ArgumentError, "memoized requires a block" unless block_given? target = singleton_class target.include(Memery) unless target.include?(Memery) memoize_methods!(target, method_names_to_memoize(method_names)) ContextualMemery.enter(target) begin yield ensure clear_memery_cache! if ContextualMemery.leave(target) end end |