Skip to content

Instantly share code, notes, and snippets.

@cqfd
Created July 10, 2013 16:41
Show Gist options
  • Save cqfd/5967917 to your computer and use it in GitHub Desktop.
Save cqfd/5967917 to your computer and use it in GitHub Desktop.
Ruby memoization exercise
require 'minitest/autorun'
module Memoization
def memoize(f, injected_cache={})
m = instance_method(f)
define_method(f) do |*args|
cache = injected_cache.clone
define_singleton_method(f) do |*args|
unless cache[args]
puts "Actually calculating..."
cache[args] = m.bind(self).call(*args)
end
cache[args]
end
send(f, *args)
end
end
end
class Bar
extend Memoization
def initialize(x)
@x = x
end
def inc
@x + 1
end
memoize :inc
end
describe Memoization do
# it "works" do
# f = Foo.new
# f.inc(123).must_equal 124
# f.inc(123).must_equal 124
# f.inc(0).must_equal 1
# f.inc(0).must_equal 1
# f.sum(1,2).must_equal 3
# f.sum(1,2).must_equal 3
# f.sum(100, 200).must_equal 300
# f.sum(100, 200).must_equal 300
# end
it "foo" do
cache = MiniTest::Mock.new
Foo = Class.new do
extend Memoization
def inc(x)
x + 1
end
memoize :inc, cache
end
f = Foo.new
cache.expect(:clone, cache, [])
cache.expect(:[]=, nil, [0])
cache.expect(:[],
f.inc(0)
end
it "makes separate caches per object" do
b1 = Bar.new(0)
b1.inc.must_equal(1)
b1.inc.must_equal(1)
b2 = Bar.new(0)
b2.inc.must_equal(1)
b2.inc.must_equal(1)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment