amair
amair

Reputation: 169

How to cache methods in ruby?

I have a ruby workflow which makes few expensive API calls. I know we have a easier way to cache things in Ruby on Rails but haven't found any common ruby gem for ruby scripts.

What is the simplest and easiest way to cache results for a method which depends on input for a pure ruby application?

//pseudo code
def get_information (id)
  user_details = expensive_api_call(id)
  return user_details
end

Upvotes: 6

Views: 5165

Answers (5)

Pascal
Pascal

Reputation: 8656

The easiest way is to use a Hash:

class ApiWithCache

  def initialize
    @cache = {}
  end

  def do_thing(id)
    expensive_api_call(id)
  end

  def do_thing_with_cache(id)
    @cache[id] ||= do_thing(id)
  end
end

Now this poses some problems that you might want to look into:

  • expiry of cached data
  • size of cache (will grow unless you also remove items. this could cause problems in long running processes)

Upvotes: 8

yegor256
yegor256

Reputation: 105210

Try zache:

require 'zache'
zache = Zache.new
x = zache.get(:x, lifetime: 15) do
  # Something very slow and expensive, which
  # we only want to execute once every 15 seconds.
end

I'm the author.

Upvotes: 0

Uysim Ty
Uysim Ty

Reputation: 141

Do it by hash global variable

def get_information(id)
    @user_details ||= {}
    @user_details[id] ||= expensive_api_call(id)
    return @user_details[id]
end

Upvotes: 0

ndnenkov
ndnenkov

Reputation: 36110

It is already pretty easy in pure ruby:

def foo(id)
  @foo[id] ||= some_expensive_operation
end

As far as gems go - check out memoist.

Upvotes: 2

Keith Bennett
Keith Bennett

Reputation: 4970

You can do this using an instance variable containing a hash, and the ||= operator, as in:

def initialize
  @user_cache = {}
  # ...
end

def get_information(id)
  @user_cache[id] ||= expensive_api_call(id)
end

||= means execute the method call and perform the assignment only if the lvalue (in this case @user_cache[id]) is falsy (nil or false). Otherwise, the value that is already in the hash is used.

Upvotes: 0

Related Questions