From: Jacob Fugal Date: 2005-10-18T04:32:24+09:00 Subject: Re: declaratively caching results of a method On 10/17/05, Brian Buckley wrote: > If I can ask a Ruby 101 question about it... Isn't "cache" in the > module (pasted below in its entirety it is so short) only a local > variable? Why does is retain state? How can one, for example, access > the cache to see the state of the cache? > > Thanks! > > --Brian > > module Memoize > MEMOIZE_VERSION = "1.0.0" > def memoize(name) > meth = method(name) > cache = {} > (class << self; self; end).class_eval do > define_method(name) do |*args| > cache[args] ||= meth.call(*args) > end > end > end > end This is the magic of closures. When you use define_method, it takes a block as argument defining the method body. This block is a closure[1]. A nifty thing about closures is that they capture the environment in which they are defined. In this case, the closure representing the body of the method can capture the cache variable from the environment in which it's defined. The cache variable itself goes out of scope at the end of the memoize method, but the object it referred to is still referred to within the closure, so the object remains accessible within that closure. Jacob Fugal [1] http://en.wikipedia.org/wiki/Closure_(computer_science)