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!
– Shot