[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

status of cache in Memoizable

matt

10/13/2008 7:16:00 PM

[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 Gray'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.

--
matt neuburg, phd = matt@tidbits.com, http://www.tidbits...
Leopard - http://www.takecontrolbooks.com/leopard-custom...
AppleScript - http://www.amazon.com/gp/product/...
Read TidBITS! It's free and smart. http://www.t...
3 Answers

Chuck Remes

10/13/2008 7:34:00 PM

0


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


James Gray

10/13/2008 7:43:00 PM

0

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 Gray II

matt

10/13/2008 10:00:00 PM

0

James Gray <james@grayproductions.net> wrote:

> 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.

Great answer, thanks! m.

--
matt neuburg, phd = matt@tidbits.com, http://www.tidbits...
Leopard - http://www.takecontrolbooks.com/leopard-custom...
AppleScript - http://www.amazon.com/gp/product/...
Read TidBITS! It's free and smart. http://www.t...