Created
October 18, 2018 20:29
-
-
Save searls/89901c5433bf930c3c4d9834c466348b to your computer and use it in GitHub Desktop.
A class-wrapping memoization dingus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def MemoMe(superclass) | |
# Ripped mostly out of | |
# https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb | |
klass = Class.new(superclass) | |
methods = superclass.instance_methods | |
methods -= [:to_s, :inspect, :=~, :!~, :===, :instance_variable_get, :instance_variable_set] | |
klass.define_method(:initialize, lambda do |*args| | |
@__memo_me_instance = superclass.new(*args) | |
end) | |
klass.module_eval do | |
methods.each do |method| | |
define_method(method, lambda do |*args, &block| | |
target = self.instance_variable_get("@__memo_me_instance")#.__getobj__ | |
cache = target.instance_variable_get("@__memo_me_store") || | |
target.instance_variable_set("@__memo_me_store", {}) | |
cache[method] ||= {} | |
if memo = cache[method][[args, block]] | |
return memo | |
else | |
cache[method][[args, block]] = target.__send__(method, *args, &block) | |
end | |
end) | |
end | |
end | |
klass.define_singleton_method :public_instance_methods do |all=true| | |
super(all) - superclass.protected_instance_methods | |
end | |
klass.define_singleton_method :protected_instance_methods do |all=true| | |
super(all) | superclass.protected_instance_methods | |
end | |
return klass | |
end | |
# Demo: | |
class Calculator | |
def add(a, b) | |
puts "Ugh adding two numbers is so expensive" | |
a + b | |
end | |
end | |
CachingCalculator = MemoMe(Calculator) | |
calculator = CachingCalculator.new | |
puts calculator.add(1, 1) | |
puts calculator.add(2, 2) | |
puts <<~TEXT | |
No more printing! Just math! | |
--- | |
TEXT | |
calculator.add(1, 1) | |
calculator.add(2, 2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment