module AttributeCache def metaclass; class << self; self; end; end def cache(attr_name, options) instance_variable_set "@#{attr_name}", options[:initial] instance_variable_set "@#{:sum}_outdated", true metaclass.instance_eval do define_method("outdate_#{attr_name}") do puts "in outdated" instance_variable_set "@#{attr_name}_outdated", true end end metaclass.class_eval %Q{ def cached_#{attr_name}(&block) if @#{attr_name}_outdated puts "in cached to update!" @#{attr_name}_outdated = false @#{attr_name} = block.call else puts "in cached to give cache!" end return @#{attr_name} end } end end class Collection include AttributeCache def initialize @array = [] cache :sum, :initial => 0 end def add(x) outdate_sum @array << x end def sum cached_sum { @array.inject {|t, e| t += e} } end end c = Collection.new puts c.public_methods(false).inspect c.add(2) c.add(3) puts c.sum puts c.sum c.add(4) puts c.sum puts c.sum
You need to create an account or log in to post comments to this site.