Memoizing with arguments
At RubyConf right now and just finished the talk about Scaling Ruby (put on by the Rails Envy guys). At the end of the talk someone asked about how to roll your own memoization when your method takes arguments. It just so happens that the app I’m working had to handle this, and here is how we did it.
Unfortunately, I cant show you the exact code, but I can give you idea behind it (and since it’s pretty simple, it should be very easy to understand).
Basically, we extended active record instances to have a “cache” method available to them so you can write something like this:
def authorized?(person)
cache :authorized_people, person.id do
ThisClass.find_by_person_id_and_authorized(person.id, true)
end
end
Under the covers, the “cache” method takes the first argument and creates an instance variable to store the cache (eg: @authorized_people_cache). The next argument is the key in the hash, and the result of the block is the value. It’s that simple. I haven’t needed to do this yet, but if you had a method that took more than one argument you could just use an array with the arguments as the key and proceed as normal.
All that said, if you’re using the new Rails (2.2, I believe) or ActiveSupport, you should just use the memoize method. It’s quite a bit more robust, and allows you to reload your memoized results.
Posted by Steve on Thursday, November 06, 2008