From: Gene Tani Date: 2005-12-09T12:27:36+09:00 Subject: Re: Transparent Caching Idiom 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) > > > > # > > 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 > > > > > > 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