From 761a633a9c0a45d76ef3ed10da97e3696c3ded79 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 3 Dec 2008 10:57:08 -0600 Subject: Add Memoizable#flush_cache to clear the cache of a specific method [#1505 state:resolved] --- activesupport/lib/active_support/memoizable.rb | 44 ++++++++++++++++---------- activesupport/test/memoizable_test.rb | 10 ++++++ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb index cd5c01cda2..9f2fd3a401 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -1,10 +1,10 @@ module ActiveSupport module Memoizable - MEMOIZED_IVAR = Proc.new do |symbol| + def self.memoized_ivar_for(symbol) "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}".to_sym end - module Freezable + module InstanceMethods def self.included(base) base.class_eval do unless base.method_defined?(:freeze_without_memoizable) @@ -19,23 +19,35 @@ module ActiveSupport end def memoize_all - methods.each do |m| - if m.to_s =~ /^_unmemoized_(.*)/ - if method(m).arity == 0 - __send__($1) - else - ivar = MEMOIZED_IVAR.call($1) - instance_variable_set(ivar, {}) + prime_cache ".*" + end + + def unmemoize_all + flush_cache ".*" + end + + def prime_cache(*syms) + syms.each do |sym| + methods.each do |m| + if m.to_s =~ /^_unmemoized_(#{sym})/ + if method(m).arity == 0 + __send__($1) + else + ivar = ActiveSupport::Memoizable.memoized_ivar_for($1) + instance_variable_set(ivar, {}) + end end end end end - def unmemoize_all - methods.each do |m| - if m.to_s =~ /^_unmemoized_(.*)/ - ivar = MEMOIZED_IVAR.call($1) - instance_variable_get(ivar).clear if instance_variable_defined?(ivar) + def flush_cache(*syms, &block) + syms.each do |sym| + methods.each do |m| + if m.to_s =~ /^_unmemoized_(#{sym})/ + ivar = ActiveSupport::Memoizable.memoized_ivar_for($1) + instance_variable_get(ivar).clear if instance_variable_defined?(ivar) + end end end end @@ -44,10 +56,10 @@ module ActiveSupport def memoize(*symbols) symbols.each do |symbol| original_method = :"_unmemoized_#{symbol}" - memoized_ivar = MEMOIZED_IVAR.call(symbol) + memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol) class_eval <<-EOS, __FILE__, __LINE__ - include Freezable + include InstanceMethods raise "Already memoized #{symbol}" if method_defined?(:#{original_method}) alias #{original_method} #{symbol} diff --git a/activesupport/test/memoizable_test.rb b/activesupport/test/memoizable_test.rb index 33f1e7fe61..069ae27eb2 100644 --- a/activesupport/test/memoizable_test.rb +++ b/activesupport/test/memoizable_test.rb @@ -128,6 +128,16 @@ class MemoizableTest < Test::Unit::TestCase assert_equal 3, @calculator.counter end + def test_flush_cache + assert_equal 1, @calculator.counter + + assert @calculator.instance_variable_get(:@_memoized_counter).any? + @calculator.flush_cache(:counter) + assert @calculator.instance_variable_get(:@_memoized_counter).empty? + + assert_equal 2, @calculator.counter + end + def test_unmemoize_all assert_equal 1, @calculator.counter -- cgit v1.2.3