# Status of cache in Memoizable

**URL:** <https://www.ruby-forum.com/t/status-of-cache-in-memoizable/150827>\
**Category:** Ruby\
**Created:** [October 13, 2008, 9:21pm UTC](https://www.ruby-forum.com/t/status-of-cache-in-memoizable/150827 "2008-10-13T21:21:00Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![matt\_neuburg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4af34b/32.png) [@matt\_neuburg](https://www.ruby-forum.com/u/matt_neuburg)\
**Post date:** [October 13, 2008, 9:21pm UTC](https://www.ruby-forum.com/t/status-of-cache-in-memoizable/150827/1 "2008-10-13T21:21:00Z")

</div>

[Backstory, skip if desired:]

In my app I found a couple of places where I could speed things up by  
memoizing. I did this manually but since I was doing exactly the same  
thing in two different places I looked for a bit of metaprogramming that  
would do generalize it. I looked at various “memoize” implementations  
and found that James G.'s Memoizable was doing almost exactly the same  
thing I was doing.

Recall how it goes:

module Memoizable  
def memoize( name, cache = Hash.new )  
original = “_unmemoized#{name}_\_”  
([Class, Module].include?(self.class) ? self :  
self.class).class\_eval do  
alias\_method original, name  
private original  
define\_method(name) { |\*args| cache[args] ||= send(original,  
\*args) }  
end  
end  
end

And to use it, you “extend Memoizable” in a class and say “memoize  
:my\_method”. This works exactly the way I want it to; like me, James is  
caching at class level, so that various instances of a class share the  
cache for this method. Naturally I can think of various concerns that  
might arise (what if your cache doesn’t return nil to mean “not found”,  
what if the cached value runs the risk of being modified after being  
returned, etc.) but I think I can cope with all that.

[The actual question:]

There’s one thing happening here I don’t understand. Let’s say you don’t  
supply a value for the “cache” parameter. So the cache is simply  
Hash.new. But where does this Hash.new live? It isn’t assigned to a  
variable name so what keeps it alive? It works, but how?

Thx - m.

---

<div class="post-metadata">

**Author:** ![matt\_neuburg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4af34b/32.png) [@matt\_neuburg](https://www.ruby-forum.com/u/matt_neuburg)\
**Post date:** [October 13, 2008, 9:38pm UTC](https://www.ruby-forum.com/t/status-of-cache-in-memoizable/150827/2 "2008-10-13T21:38:05Z")

</div>

On Oct 13, 2008, at 2:17 PM, matt neuburg wrote:

> [snip]
> 
> [The actual question:]
> 
> There’s one thing happening here I don’t understand. Let’s say you  
> don’t  
> supply a value for the “cache” parameter. So the cache is simply  
> Hash.new. But where does this Hash.new live? It isn’t assigned to a  
> variable name so what keeps it alive? It works, but how?

This line here keeps the reference to cache alive:

define\_method(name) { |\*args| cache[args] ||= send(original, \*args) }

This is defining a new method and knows to return the cached value or  
send the arguments to the original unmemoized method so it can compute  
your value.

cr

---

<div class="post-metadata">

**Author:** ![matt\_neuburg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4af34b/32.png) [@matt\_neuburg](https://www.ruby-forum.com/u/matt_neuburg)\
**Post date:** [October 13, 2008, 9:46pm UTC](https://www.ruby-forum.com/t/status-of-cache-in-memoizable/150827/3 "2008-10-13T21:46:19Z")

</div>

On Oct 13, 2008, at 2:17 PM, matt neuburg wrote:

> There’s one thing happening here I don’t understand. Let’s say you  
> don’t  
> supply a value for the “cache” parameter. So the cache is simply  
> Hash.new. But where does this Hash.new live? It isn’t assigned to a  
> variable name so what keeps it alive? It works, but how?

That variable is kept alive thanks to the magic of closures. The  
block passed to define\_method() references the variable, so it will  
exist as long as that closure does. Think of it as private storage  
that only that block uses.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![matt\_neuburg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4af34b/32.png) [@matt\_neuburg](https://www.ruby-forum.com/u/matt_neuburg)\
**Post date:** [October 14, 2008, 12:06am UTC](https://www.ruby-forum.com/t/status-of-cache-in-memoizable/150827/4 "2008-10-14T00:06:24Z")

</div>

James G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> that block uses.  
> Great answer, thanks! m.
