Skip to content

Instantly share code, notes, and snippets.

@wkjagt
Last active September 29, 2015 17:45
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 wkjagt/5a4e63755e085e89c5bc to your computer and use it in GitHub Desktop.
Save wkjagt/5a4e63755e085e89c5bc to your computer and use it in GitHub Desktop.
Ruby Memoize

Memoize memoizes function return values based on class name, method name, and arguments. This means that this only works for functions that use state / have side effects.

module Memoize
  def memoize(definition)	
    self.send(:alias_method, "__original_#{definition}", definition)

    define_method definition, Proc.new { |*args|
      @__memo ||= {}

      key = "#{self.class.name}##{definition}/#{args.hash}"
      return @__memo[key] if @__memo.key?(key)

      @__memo[key] = send("__original_#{definition}", *args)
    }
  end
end

Usage

class A
  class B
    extend Memoize
  
    def heavy_calculation(a, b)
      p "calling the original"
      a * b
    end
    
    memoize :heavy_calculation
  end	
end

b = A::B.new

p b.heavy_calculation(4, 20)
# "calling the original"
# 80
p b.heavy_calculation(4, 20)
# 80
p b.heavy_calculation(2, 20)
# "calling the original"
# 40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment