Namespace

Files

Memoizable

Memoization is an optimization technique used primarily to speed up programs by having function calls avoid repeating the calculation of results for previously-processed inputs.

When you "memoize" a method/function using Memoizable its results are cached so that later calls return results from the cache instead of recalculating them.

class T
  include Memoizable

  def initialize(a)
    @a = a
  end

  def a
    "#{@a ^ 3 + 4}"
  end

  memoize :a
end

t = T.new(10)
(t.a.__id__ == t.a.__id__)  #=> true

This method can also be used at the instance level to cache singleton (qua class) methods by including it in the singleton class.

Public Class Methods

append_features(base) click to toggle source
# File lib/facets/supplemental/facets/memoizable.rb, line 44
def self.append_features(base)
  Module == base ? super(base) : base.extend(self)
end
cache() click to toggle source
# File lib/facets/supplemental/facets/memoizable.rb, line 39
def self.cache
  @cache
end

Public Instance Methods

memoize(*method_names) click to toggle source

Directive for making your functions faster by trading space for time. When you "memoize" a method/function using memoize its results are cached so that later calls with the same arguments return results from the cache instead of recalculating them.

The memoize method also handles a few options to alter behavior of the memoization:

:class     => true      cache per-class not per-object
:freeze    => true      freeze the memoized return values
:arguments => false     do not index cache by arguments
# File lib/facets/supplemental/facets/memoizable.rb, line 60
def memoize(*method_names)
  options = Hash === method_names.last ? method_names.pop : {}

  options[:arguments] = true if options[:arguments].nil?  # default to true

  ref = options[:class]     ? 'self.class.name'       : 'self'
  frz = options[:freeze]    ? '.freeze'               : ''
  arg = options[:arguments] ? '[__a__, block_given?]' : 'nil'

  code = ""
  method_names.each do |m|
    code <<         alias_method '#{ m }:memo', '#{ m }'        private '#{ m }:memo'        def #{ m }(*__a__,&__b__)          c = Memoizable.cache[#{ref}][:'#{ m }']          k = #{arg}          if c.has_key?(k)            c[k]          else            c[k] = __send__('#{ m }:memo',*__a__,&__b__)#{frz}          end        end
  end
  module_eval(code)
end
rememoize(*method_names) click to toggle source

Remove the memoized value from the memoization cache. The next time a memoized methos is called if will be remomoized.

# File lib/facets/supplemental/facets/memoizable.rb, line 91
def rememoize(*method_names)
  if Memoizable.cache[self]
    if method_names.empty?
      Memoizable.cache.delete(self)
    else
      method_names.each do |m|
        Memoizable.cache[self].delete(m.to_sym)
      end
    end
  end
  if Memoizable.cache[self.class.name]
    if method_names.empty?
      Memoizable.cache.delete(self.class.name)
    else
      method_names.each do |m|
        Memoizable.cache[self.class.name].delete(m.to_sym)
      end
    end
  end
end
unmemoize(*method_names) click to toggle source
# File lib/facets/supplemental/facets/memoizable.rb, line 113
def unmemoize(*method_names)
  rememoize(*method_names)
  method_names.each do |m|
    alias_method name, "#{ m }:memo"
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.