pax_global_header00006660000000000000000000000064125276523540014525gustar00rootroot0000000000000052 comment=19157299afac49b0e9b5fc8712882d9e34d43fd1 ruby-dirty-memoize-0.0.4/000077500000000000000000000000001252765235400153035ustar00rootroot00000000000000ruby-dirty-memoize-0.0.4/History.txt000066400000000000000000000000771252765235400175110ustar00rootroot00000000000000=== 0.0.4 / 2011-01-26 * Better specs * Build managed with Hoe ruby-dirty-memoize-0.0.4/LICENSE.txt000066400000000000000000000020421252765235400171240ustar00rootroot00000000000000Copyright (c) 2009 Claudio Bustos Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ruby-dirty-memoize-0.0.4/Manifest.txt000066400000000000000000000003021252765235400176050ustar00rootroot00000000000000History.txt LICENSE.txt Manifest.txt README.txt Rakefile examples/only_reader.rb examples/reader_and_writer.rb lib/dirty-memoize.rb spec/dirty_memoize_spec.rb spec/spec.opts spec/spec_helper.rb ruby-dirty-memoize-0.0.4/README.txt000066400000000000000000000031541252765235400170040ustar00rootroot00000000000000= dirty-memoize * http://github.com/clbustos/dirty-memoize == DESCRIPTION Like Memoize, but designed for mutable and parametizable objects Use when: 1. You have one expensive method (\compute) which set many internal variables. So, is preferable lazy evaluation of these dependent variables. 2. The expensive operation depends on one or more parameters 3. Changes on one or more parameters affect all dependent variables 4. You may want to hide the call of 'compute' operation 5. The user could want test several different parameters values == SYNOPSIS By default, the method to compute should be called \#compute. Set constant DIRTY_COMPUTE to the name of other method if you need it Example: require 'dirty-memoize' class Factorial include DirtyMemoize attr_reader :result attr_writer :n dirty_memoize :result dirty_writer :n def initialize @n=nil @result=nil end def fact(n) return 1 if n==1 n*(fact(n-1)) end def compute puts "Computing the factorial!" @result=fact(@n) end end a=Factorial.new a.n=10 puts "Our object is dirty: #{a.dirty?}" puts "The result is: #{a.result}" puts "Our object is no longer dirty: #{a.dirty?}" puts "And the result is cached without calling the compute method: #{a.result}" puts "Now, n is changed to 5" a.n=5 # Object is now dirty. So, compute will be called when we get result puts "The result is: #{a.result}" == Sugestions * Fork, modify and do wathever you need with it. == Copyright Copyright (c) 2010-2011 Claudio Bustos. See LICENSE for details. ruby-dirty-memoize-0.0.4/Rakefile000066400000000000000000000007461252765235400167570ustar00rootroot00000000000000$:.unshift(File.expand_path(File.dirname(__FILE__)+"/lib")) $:.unshift(File.expand_path(File.dirname(__FILE__))) require 'rubygems' require 'rake' require 'hoe' require 'dirty-memoize' require 'rspec' require 'rspec/core/rake_task' Hoe.plugin :git h=Hoe.spec 'dirty-memoize' do self.testlib=:rspec self.rspec_options << "-c" << "-b" self.developer('Claudio Bustos', 'clbustos_at_gmail.com') self.version=DirtyMemoize::VERSION self.extra_dev_deps << ["rspec",">=2.0"] end ruby-dirty-memoize-0.0.4/data.tar.gz.sig000066400000000000000000000004001252765235400201160ustar00rootroot00000000000000hh*Bie) _а6w1uN4 T W} {FؿpɌv%iB)+-A)7:ѼcBܶҚDsTr<אǔɼqur9+uA ^,{0.`l,샅@+Q m~CCp05 ) )Te JZd)0i;"3b׀}c gQ<6܎ZFruby-dirty-memoize-0.0.4/examples/000077500000000000000000000000001252765235400171215ustar00rootroot00000000000000ruby-dirty-memoize-0.0.4/examples/only_reader.rb000066400000000000000000000015531252765235400217550ustar00rootroot00000000000000$:.unshift(File.expand_path(File.dirname(__FILE__)+"/../lib")) # This example shows the use of dirty_memoize without dirty_writer. # When we call the method marked with dirty_memoize on a dirty object # compute method is called. require 'dirty-memoize' class Factorial include DirtyMemoize attr_reader :result dirty_memoize :result def initialize(n) @n=n @result=nil end def fact(n) return 1 if n==1 n*(fact(n-1)) end def compute puts "Computing the factorial!" @result=fact(@n) end end a=Factorial.new(10) puts "Our object is dirty: #{a.dirty?}" puts "The result is: #{a.result}" puts "Our object is no longer dirty: #{a.dirty?}" puts "And the result is cached without calling the compute method: #{a.result}" a.clean_cache # Object is now dirty. So, compute will be called when we get result puts "The result is: #{a.result}" ruby-dirty-memoize-0.0.4/examples/reader_and_writer.rb000066400000000000000000000017411252765235400231310ustar00rootroot00000000000000$:.unshift(File.expand_path(File.dirname(__FILE__)+"/../lib")) # This example shows the use of dirty_memoize with dirty_writer. # When we call the method marked with dirty_memoize on a dirty object, # compute method is called. # Setting a value on a dirty_writer set the object to dirty require 'dirty-memoize' class Factorial include DirtyMemoize attr_reader :result attr_writer :n dirty_memoize :result dirty_writer :n def initialize @n=nil @result=nil end def fact(n) return 1 if n==1 n*(fact(n-1)) end def compute puts "Computing the factorial!" @result=fact(@n) end end a=Factorial.new a.n=10 puts "Our object is dirty: #{a.dirty?}" puts "The result is: #{a.result}" puts "Our object is no longer dirty: #{a.dirty?}" puts "And the result is cached without calling the compute method: #{a.result}" puts "Now, n is changed to 5" a.n=5 # Object is now dirty. So, compute will be called when we get result puts "The result is: #{a.result}" ruby-dirty-memoize-0.0.4/lib/000077500000000000000000000000001252765235400160515ustar00rootroot00000000000000ruby-dirty-memoize-0.0.4/lib/dirty-memoize.rb000066400000000000000000000044521252765235400212010ustar00rootroot00000000000000# Like Memoize, but designed for mutable and parametizable objects # # Use when: # 1. You have one expensive method (\#compute) which set many internal # variables. So, is preferable lazy evaluation of these dependent variables. # 2. The expensive operation depends on one or more parameters # 3. Changes on one or more parameters affect all dependent variables # 4. You may want to hide the call of 'compute' operation # 5. The user could want test several different parameters values # # By default, the method to compute should be called \#compute. # Set constant DIRTY_COMPUTE to the name of other method if you need it # # Example: # class ExpensiveCalculation # extend DirtyMemoize # attr_accessor :y, :z # def initialize(y=nil,z=nil) # @y=y # @z=z # def compute # @a=@y*1000+@z*1000 # end # def a # @a.nil? nil : "This is the value: #{@a}" # end # # end # puts ExpensiveCalculation.new(1,2).a module DirtyMemoize VERSION="0.0.4" # Trick from http://github.com/ecomba/memoizable def self.included(receiver) #:nodoc: receiver.extend DirtyMemoize::ClassMethods end module ClassMethods # Set variables which def dirty_writer(*independent) independent.each do |sym| sym=sym.to_s+"=" alias_method((sym.to_s+"_without_dirty").intern, sym) define_method(sym) do |*args| @dirty=:true send(sym.to_s+"_without_dirty", *args) end end end def dirty_memoize(*dependent) dependent.each do |sym| alias_method((sym.to_s+"_without_dirty").intern, sym) define_method(sym) do |*args| if(dirty?) clean_cache if self.class.const_defined? "DIRTY_COMPUTE" send(self.class.const_get("DIRTY_COMPUTE")) else send(:compute) end @compute_count||=0 @compute_count+=1 @dirty=:false end @cache[sym]||=Hash.new @cache[sym][args]||=send(sym.to_s+"_without_dirty", *args) end end end end # end of ClassMethods # Is the object dirty? def dirty? @dirty||=:true @dirty==:true end # Number of compute's runs def compute_count @compute_count||=0 end def clean_cache @cache=Hash.new @dirty=:true end endruby-dirty-memoize-0.0.4/metadata.gz.sig000066400000000000000000000004001252765235400202000ustar00rootroot00000000000000u[:\#ݵ_co :V'dB?60~h\+&0?LrA'16Ґ1ǗzVM֠!<4n>?ǧQh+ͭA[̑;Z̠nf6{s=`vdA\eHA<+e}i }lOW ϕQI7)޼Kh7pOI[ Wk;]h(79r߆V3, jI i9"3V@,sruby-dirty-memoize-0.0.4/metadata.yml000066400000000000000000000073041252765235400176120ustar00rootroot00000000000000--- !ruby/object:Gem::Specification name: dirty-memoize version: !ruby/object:Gem::Version prerelease: false segments: - 0 - 0 - 4 version: 0.0.4 platform: ruby authors: - Claudio Bustos autorequire: bindir: bin cert_chain: - | -----BEGIN CERTIFICATE----- MIIDMjCCAhqgAwIBAgIBADANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhjbGJ1 c3RvczEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t MB4XDTEwMDMyOTIxMzg1NVoXDTExMDMyOTIxMzg1NVowPzERMA8GA1UEAwwIY2xi dXN0b3MxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf8JVMGqE7m5kYb+PNN neZv2pcXV5fQCi6xkyG8bi2/SIFy/LyxuvLzEeOxBeaz1Be93bayIUquOIqw3dyw /KXWa31FxuNuvAm6CN8fyeRYX/ou4cw3OIUUnIvB7RMNIu4wbgeM6htV/QEsNLrv at1/mh9JpqawPrcjIOVMj4BIp67vmzJCaUf+S/H2uYtSO09F+YQE3tv85TPeRmqU yjyXyTc/oJiw1cXskUL8UtMWZmrwNLHXuZWWIMzkjiz3UNdhJr/t5ROk8S2WPznl 0bMy/PMIlAbqWolRn1zl2VFJ3TaXScbqImY8Wf4g62b/1ZSUlGrtnLNsCYXrWiso UPUCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFGu9 rrJ1H64qRmNNu3Jj/Qjvh0u5MA0GCSqGSIb3DQEBBQUAA4IBAQCV0Unka5isrhZk GjqSDqY/6hF+G2pbFcbWUpjmC8NWtAxeC+7NGV3ljd0e1SLfoyBj4gnFtFmY8qX4 K02tgSZM0eDV8TpgFpWXzK6LzHvoanuahHLZEtk/+Z885lFene+nHadkem1n9iAB cs96JO9/JfFyuXM27wFAwmfHCmJfPF09R4VvGHRAvb8MGzSVgk2i06OJTqkBTwvv JHJdoyw3+8bw9RJ+jLaNoQ+xu+1pQdS2bb3m7xjZpufml/m8zFCtjYM/7qgkKR8z /ZZt8lCiKfFArppRrZayE2FVsps4X6WwBdrKTMZ0CKSXTRctbEj1BAZ67eoTvBBt rpP0jjs0 -----END CERTIFICATE----- date: 2011-01-26 00:00:00 -03:00 default_executable: dependencies: - !ruby/object:Gem::Dependency name: rspec prerelease: false requirement: &id001 !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version segments: - 2 - 0 version: "2.0" type: :development version_requirements: *id001 - !ruby/object:Gem::Dependency name: hoe prerelease: false requirement: &id002 !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version segments: - 2 - 8 - 0 version: 2.8.0 type: :development version_requirements: *id002 description: |- Like Memoize, but designed for mutable and parametizable objects Use when: 1. You have one expensive method (\compute) which set many internal variables. So, is preferable lazy evaluation of these dependent variables. 2. The expensive operation depends on one or more parameters 3. Changes on one or more parameters affect all dependent variables 4. You may want to hide the call of 'compute' operation 5. The user could want test several different parameters values email: - clbustos_at_gmail.com executables: [] extensions: [] extra_rdoc_files: - History.txt - LICENSE.txt - Manifest.txt - README.txt files: - History.txt - LICENSE.txt - Manifest.txt - README.txt - Rakefile - examples/only_reader.rb - examples/reader_and_writer.rb - lib/dirty-memoize.rb - spec/dirty_memoize_spec.rb - spec/spec.opts - spec/spec_helper.rb has_rdoc: true homepage: http://github.com/clbustos/dirty-memoize licenses: [] post_install_message: rdoc_options: - --main - README.txt require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version segments: - 0 version: "0" required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version segments: - 0 version: "0" requirements: [] rubyforge_project: dirty-memoize rubygems_version: 1.3.7 signing_key: specification_version: 3 summary: "Like Memoize, but designed for mutable and parametizable objects Use when: 1" test_files: [] ruby-dirty-memoize-0.0.4/spec/000077500000000000000000000000001252765235400162355ustar00rootroot00000000000000ruby-dirty-memoize-0.0.4/spec/dirty_memoize_spec.rb000066400000000000000000000054241252765235400224610ustar00rootroot00000000000000require File.expand_path(File.dirname(__FILE__) + '/spec_helper') class ExpensiveClass attr_writer :x, :y include DirtyMemoize def initialize @a=nil @b=nil @x='x' @y='y' end def set_a(aa) @a=aa end def compute @a=@x @b=@y end def a "@a=#{@a}" end def b "@b=#{@b}" end dirty_writer :x, :y dirty_memoize :a, :b end class ExpensiveClass2 < ExpensiveClass DIRTY_COMPUTE=:compute2 def compute2 @a=@x+".2" end end describe DirtyMemoize, "extended object" do before do @ec=ExpensiveClass.new end subject { @ec } context "when instanciated" do it { should be_dirty} it "should initialize with number of computation to 0" do @ec.compute_count.should==0 end it "read inmediatly the correct value" do @ec.a.should=='@a=x' end end context "when reads 'dirty' attributes " do before do @ec.a end it 'call compute' do @ec.compute_count.should==1 end it{ should_not be_dirty} it "call compute once and only once" do 5.times {@ec.a} @ec.compute_count.should==1 end end context "calls dirty writers before dirty getter" do before do @ec.x="cache" end it { should be_dirty} it "doesn't compute anything" do @ec.compute_count.should==0 end it "doesn't change internal variables" do @ec.instance_variable_get("@a").should be_nil end end describe "when calls dirty getter after call dirty writer" do before do @ec.x="cache" @ec.a end it { @ec.should_not be_dirty} it "calls compute only once" do @ec.compute_count.should==1 end it "set value of internal variable" do @ec.instance_variable_get("@a").should=='cache' end it 'set getter method with a different value' do @ec.a.should=='@a=cache' end end describe "uses cache" do before do @ec.x='cache' @ec.a @ec.set_a('not_cache') end it "changing internal doesn't start compute" do @ec.compute_count.should==1 end it {should_not be_dirty} it "doesn't change cache value" do @ec.a.should=='@a=cache' end describe "when cleaning cache" do before do @ec.clean_cache end it {@ec.should be_dirty} it "doesn't call compute" do @ec.compute_count.should==1 end describe "when get dirty attribute" do it "returns correct value and call compute again" do @ec.a.should=='@a=cache' @ec.compute_count.should==2 end end end end describe "could call other computation method" do it "using DIRTY_COMPUTER" do @ec2=ExpensiveClass2.new @ec2.x='cache' @ec2.a.should=='@a=cache.2' @ec2.compute_count.should==1 end end end ruby-dirty-memoize-0.0.4/spec/spec.opts000066400000000000000000000000141252765235400200710ustar00rootroot00000000000000--color -f sruby-dirty-memoize-0.0.4/spec/spec_helper.rb000066400000000000000000000004561252765235400210600ustar00rootroot00000000000000$:.unshift(File.expand_path(File.dirname(__FILE__)+"/../lib")) begin require 'simplecov' SimpleCov.start do add_filter "/spec/" add_group "Libraries", "lib" end rescue LoadError end require 'rspec' require 'dirty-memoize.rb' class String def deindent gsub /^[ \t]*/, '' end end