Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Attribute Cache (See related posts)

Sometimes, you don't want to calculate the value of an attribute every time--like the sum of an array. However, you don't want it cached on the outside of the object since that makes for messy code. But you seem to cache things over and over again inside objects. Here's a module AttributeCache that does a little meta programming to make attribute caching a little bit easier. more details at http://webjazz.blogspot.com/2007/05/ruby-snippet-caching-object-attributes.html

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.


Click here to browse all 5140 code snippets

Related Posts