Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
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

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.