From: Alex Combas Date: 2006-01-28T14:04:55+09:00 Subject: Re: Memoization? On 1/27/06, James Edward Gray II wrote: > You bet. It's a single file. Just download the source from > RubyForge and move /lib/memoize.rb into your path. It will work just > fine. > Thanks James! Wow, dont want to fanboy here, but wow. $cat fib.rb def fib(n) return n if n < 2 fib(n-1) + fib(n-2) end puts fib(35) $ time ruby fib.rb 9227465 real 0m41.121s user 0m37.128s sys 0m3.854s $cat mem_fib.rb require "memoize" include Memoize def fib(n) return n if n < 2 fib(n-1) + fib(n-2) end memoize(:fib) puts fib(35) $ time ruby mem_fib.rb 9227465 real 0m0.011s user 0m0.008s sys 0m0.003s Yikes! This is definitly something I'm going to need to learn to use, and use as often as possible. So anywho, took a quick peek at memoize.rb and was again just blown away but this time because the entire file was only 39 lines of code including white space! How can this be? Unfortuantely, there are no comments to be had, so I was wondering if someone would be so kind as to reply with inserted comments in the code, (yes I know ruby is supposed to be readable, but im new, ok? :-) Just as a precaution so that I don't make any weird assumptions, something I'm prone to do. This would be greatly appreciated. Bored? Nothing to do on a Friday night? Well here is some source. Comment away all you bored rubyists! module Memoize MEMOIZE_VERSION = "1.2.0" # Memoize the method +name+. If +file+ is provided, then the method results # are stored on disk rather than in memory. This consumes virtually no # memory and is persistant. def memoize(name, file=nil) meth = method(name) if file cache = Hash.new.update(Marshal.load(File.read(file))) rescue {} else cache = {} end if file (class << self; self; end).class_eval do define_method(name) do |*args| unless cache.has_key?(args) cache[args] = meth.call(*args) File.open(file, "wb+"){|f| Marshal.dump(cache, f) } end cache[args] end end else (class << self; self; end).class_eval do define_method(name) do |*args| if cache.has_key?(args) cache[args] else cache[args] ||= meth.call(*args) end end end end cache end -- Alex Combas http://noodlejunkie.blogspot.com/