Skip to content

Instantly share code, notes, and snippets.

@AndrewRadev
Last active August 29, 2015 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrewRadev/8767627 to your computer and use it in GitHub Desktop.
Save AndrewRadev/8767627 to your computer and use it in GitHub Desktop.
Caching decorator in ruby 2.1
# In ruby 2.1, the method definition returns the name of the method. As a
# result, python-decorator-like class methods can be created.
#
module CachingDecorator
def cached(method_name)
alias_method("_generate_#{method_name}", method_name)
define_method(method_name) do
@_caching_decorator_cache ||= {}
if not @_caching_decorator_cache.key?(method_name)
@_caching_decorator_cache[method_name] = method("_generate_#{method_name}").call
end
@_caching_decorator_cache[method_name]
end
# Return the method name, so we could chain decorators
method_name
end
end
# As example usage, a stupid wrapper around net/http
require 'net/http'
class Http
extend CachingDecorator
def initialize(url)
@url = url
end
def body
response.body
end
def headers
response.to_hash
end
# We could do this:
#
# private
#
# def response
# @response ||= Net::HTTP.get_response(URI(@url))
# end
#
# But, we could also:
private cached def response
uri = URI(@url)
Net::HTTP.get_response(uri)
end
end
rubygems = Http.new('http://rubygems.org')
puts "Headers:"
puts rubygems.headers
puts "Body:"
puts rubygems.body[0..50].inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment