On Jan 27, 2006, at 11:04 PM, Alex C. wrote:
module Memoize
MEMOIZE_VERSION = “1.2.0”
Set a constant to the module version, so user code can check it as
needed.
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)
Grab a reference to the original method.
if file cache = Hash.new.update(Marshal.load(File.read(file)))
rescue {}
else
cache = {}
end
Load an existing cache file, if requested and one exists. Otherwise,
set the cache to an empty Hash.
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
This is the singleton class trick James B. described. It this
version, the cache is checked for an entry with all the arguments it
was just called with. If it’s not found, the original method is
triggered to add that entry to the cache. The file is also modified
to contain the new entry. Either way, the cache now has the needed
entry, which is returned.
end
Exact same thing, minus the file dump. In fact, that whole if/else/
end chunk of code could be simplified to:
(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) } if file
end
cache[args]
end
end
cache
Return the cache we will use for user code to examine/modify, if
desired.
end
Hope that helps.
James Edward G. II