Skip to content
Cache based on arguments AND object state; store in memcached, redis, or in-process. Like alias_method, but it's cache_method! One step beyond memoization.
Ruby
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
lib
test
.gitignore
Gemfile
README.rdoc
Rakefile
cache_method.gemspec

README.rdoc

cache_method

It's like alias_method, but it's cache_method!

Example

require 'cache_method'
class Blog
  attr_reader :name
  attr_reader :url

  def initialize(name, url)
    @name = name
    @url = url
  end

  # The method we're going to cache
  def get_latest_entries
    sleep 5
  end

  # What you get with this gem
  cache_method :get_latest_entries

  # Per Ruby convention, a "hash code" representing the internal state of an instance.
  # It's recommended that you construct a String or a Hash and then call #hash on it.
  def hash
    { :name => name, :url => url }.hash
  end
end

Then you can do

my_blog.get_latest_entries => first time won't be cached
my_blog.get_latest_entries => second time will come from cache

And clear them too

my_blog.clear_method_cache :get_latest_entries

(which doesn't delete the rest of your cache)

Configuration (and supported cache clients)

You need to set where the cache will be stored:

CacheMethod.config.storage = Memcached.new '127.0.0.1:11211'

or

CacheMethod.config.storage = Redis.new

or this might even work…

CacheMethod.config.storage = Rails.cache

See Config for the full list of supported caches.

Defining a #hash method (not the same as #to_hash)

Since we're not pure functional programmers, sometimes cache hits depend on object state in addition to method arguments. To illustrate:

my_blog.get_latest_entries

get_latest_entries doesn't take any arguments, so it must depend on my_blog.url or something. This works because we define:

class Blog
  # [...]
  def hash
    { :name => name, :url => url }.hash
  end
  # [...]
end

You should follow Ruby convention and have #hash return a Fixnum.

Ideally, you should try to make a String or a Hash and call the standard #hash on that.

Note: this is NOT the same thing as #to_hash! That returns a Hash. What we want is an integer “hash code.”

Rationale

  • It should be easy to cache a method using memcached.

  • The main clients should be supported

    • memcache-client (for people who use the Rails default)

    • dalli (for people on heroku)

    • memcached (for people using Evan Weaver's ultra-fast gem)

    • redis (for people who like that sort of thing, but you won't get expiration)

  • It should be easy to uncache a method without clearing the whole cache

  • It should be easy to cache instance methods

  • It should be easy to cache methods that depend on object state

Copyright

Copyright 2011 Seamus Abshere

Something went wrong with that request. Please try again.