Gene Tani wrote: > Daniel Schierbeck wrote: >> beng wrote: >>> I've made good use of this idiom recently, and wanted to share it. >>> >>> Once this code is active, any method named with a "_c" suffix is >>> automatically cached. The method is assumed to follow a simple >>> contract: It performs no side-effects / mutations, and it's >>> arguments properly implement "Object.hash". >>> >>> This is specifically useful for expensive but functional >>> calculations. Enjoy! >>> >>> --Ben (b / gimpert.com) >>> >>> # <code> >>> class Class >>> >>> alias old_new new >>> def new(*args, &block) >>> Class.defc_wrap(old_new(*args, &block)) >>> end >>> >>> def Class.defc_wrap(obj) >>> klass = obj.class >>> defc_methods = obj.methods.select { |n| n =~ /_c$/ } >>> defc_methods.each do |name| >>> meth = obj.method(name) >>> wrapped_name = Class.defc_next_name(klass) >>> cache = klass.class_eval("@#{wrapped_name} = {}") >>> wrapper = Proc.new do |*args_a| >>> arg_hash = args_a.hash >>> if cache.has_key?(arg_hash) >>> cache[arg_hash] >>> else >>> cache[arg_hash] = meth.call(*args_a) >>> end >>> end >>> klass.send(:alias_method, wrapped_name, name) >>> klass.send(:define_method, name, wrapper) >>> end >>> obj >>> end >>> >>> def Class.defc_next_name(obj) >>> klass = obj.class >>> i = 1 >>> i += 1 while obj.respond_to?("_defc_#{i}") || >>> obj.instance_variables.member?("@_defc_#{i}") >>> "_defc_#{i}" >>> end >>> >>> end >>> </code> >>> >> >> Neat. Though it would be cool if the methods that were to be cached >> were chosen through a class method rather than a method name suffix. >> >> class Klass >> def foo; end >> def bar; end >> cached_method :foo, :bar >> end >> >> >> Cheers, >> Daniel > I got this bookmarked, When i get time, i'll have to compare to prior > thread on memozing > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/155159 > http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/155170 See also: http://raa.ruby-lang.org/project/memoize/ Kind regards robert