lib/more/facets/memoize.rb in facets-2.6.0 vs lib/more/facets/memoize.rb in facets-2.7.0

- old
+ new

@@ -1,113 +2 @@ -# = Memoize -# -# Directive for making your functions faster by trading -# space for time. When you "memoize" a method/function -# its results are cached so that later calls with the -# same arguments returns results in the cache instead -# of recalculating them. -# -# class T -# def initialize(a) -# @a = a -# end -# def a -# "#{@a ^ 3 + 4}" -# end -# memoize :a -# end -# -# t = T.new(1) -# t.a.__id__ == t.a.__id__ #=> true -# -# == Authors -# -# * trans -# * rtb -# -# == Copying -# -# Copyright (c) 2005 Robert Feldt -# -# Ruby License -# -# This module is free software. You may use, modify, and/or redistribute this -# software under the same terms as Ruby. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. - -#require 'facets/memoizer' - -# -class Module - - # Directive for making your functions faster by trading - # space for time. When you "memoize" a method/function - # its results are cached so that later calls with the - # same arguments returns results in the cache instead - # of recalculating them. - # - # class T - # def initialize(a) - # @a = a - # end - # def a - # "#{@a ^ 3 + 4}" - # end - # memoize :a - # end - # - # t = T.new - # t.a.__id__ == t.a.__id__ #=> true - # - def memoize(*meths) - meths.each do |meth| - old = instance_method(meth) - new = proc do |*args| - mc = ((@_MEMOIZE_CACHE ||= {})[meth] ||= {}) - if mc.has_key? args - mc[args] - else - mc[args] = old.bind(self).call(*args) - end - end - send(:define_method, meth, &new) - end - end - -end - -# This allows memoize to work in main and instance scope too. -def memoize(*args) - Object.memoize(*args) -end - -module Kernel #:nodoc: - - # Object#cache is essentially like Module#memoize except - # it can also be used on singleton/eigen methods. - # OTOH, memoize's implementation is arguably better for it's - # use of #bind instead of #alias. Eventually the two implmenations - # should be reconciled with a single implementation. - # - def cache m = nil - if m - (Module === self ? self : (class << self; self; end)).module_eval <<-code - alias_method '__#{ m }__', '#{ m }' - def #{ m }(*__a__,&__b__) - c = cache['#{ m }'] - k = [__a__,__b__] - if c.has_key? k - c[k] - else - c[k] = __#{ m }__(*__a__,&__b__) - end - end - code - end - @cache ||= Hash::new{|h,k| h[k]={}} - end - -end - +require 'facets/once'