From: Ezra Zygmuntowicz Date: 2008-02-20T03:40:02+09:00 Subject: Re: Object#freeze as a basis for caching of method results? Hi~ On Feb 19, 2008, at 8:01 AM, Shot (Piotr Szotkowski) wrote: > Hello, ruby-talk. > > After profiling my code I figured out I might want to attempt some > caching of results obtained in ‘heavy’ methods. Is there an idiomatic > way to do method-results caching in Ruby? > > The first thing that came to my mind as a mean to ensure the cache’s > ‘freshness’ is to freeze the object in question. Does this make sense? > > For example, assume that a Blanket is a Set of Blocks, and > that there’s a computation-intesive method ‘separations’: > > > > class Blanket < Set > > def separations > seps = Set[] > # some ‘heavy’ code that builds seps > seps > end > > end > > > > Would the below make sense? > > > > class Blanket < Set > > def freeze > each { |block| block.freeze } > super > end > > def separations > return @seps if @seps > @seps = Set[] > # the ‘heavy’ code from that builds @seps this time > freeze > @seps > end > > end > > > > I guess my question boils down to what does exactly Object#freeze > prevent from being modified – simply all the properties? > > If so, does it mean I can only have one method like the above (because > if some other method did any freezing, I couldn’t initialise the @seps > cache when the first call to separations occurs)? > > Is there any ‘best practice’ in Ruby > with regards to caching method results? > > Is there any obvious other approach to such caching? (I thought about > having a @cache instance variable that would get reset on object > changes, but I’m not sure how to obtain all the list of methods that > can change an object – i.e., methods that throw error when a given > object is frozen.) > > Thanks in advance for any replies/suggestions/insights! > The usual idiom for caching heavy results is something like this: def foo @foo ||= some_long_calculation end Cheers- - Ezra Zygmuntowicz -- Founder & Software Architect -- ezra@engineyard.com -- EngineYard.com