Permalink
Browse files

memoize_ and unmemoize_all

  • Loading branch information...
1 parent 3284fbb commit 3fc9a67c04bade858e7ac7eb8cd94eec6a63ec27 @jeremy jeremy committed Aug 14, 2008
Showing with 48 additions and 18 deletions.
  1. +33 −18 activesupport/lib/active_support/memoizable.rb
  2. +15 −0 activesupport/test/memoizable_test.rb
@@ -10,25 +10,37 @@ def self.included(base)
end
def freeze_with_memoizable
- unless frozen?
- methods.each do |method|
- if method.to_s =~ /^_unmemoized_(.*)/
- begin
- __send__($1).freeze
- rescue ArgumentError
- end
+ memoize_all unless frozen?
+ freeze_without_memoizable
+ end
+
+ def memoize_all
+ methods.each do |m|
+ if m.to_s =~ /^_unmemoized_(.*)/
+ if method(m).arity == 0
+ __send__($1)
+ else
+ ivar = :"@_memoized_#{$1}"
+ instance_variable_set(ivar, {})
end
end
end
+ end
- freeze_without_memoizable
+ def unmemoize_all
+ methods.each do |m|
+ if m.to_s =~ /^_unmemoized_(.*)/
+ ivar = :"@_memoized_#{$1}"
+ instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
+ end
+ end
end
end
def memoize(*symbols)
symbols.each do |symbol|
- original_method = "_unmemoized_#{symbol}"
- memoized_ivar = "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}"
+ original_method = :"_unmemoized_#{symbol}"
+ memoized_ivar = :"@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}"
class_eval <<-EOS, __FILE__, __LINE__
include Freezable
@@ -38,21 +50,24 @@ def memoize(*symbols)
if instance_method(:#{symbol}).arity == 0
def #{symbol}(reload = false)
- if !reload && defined? #{memoized_ivar}
- #{memoized_ivar}
- else
- #{memoized_ivar} = #{original_method}
+ if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty?
+ #{memoized_ivar} = [#{original_method}]
end
+ #{memoized_ivar}[0]
end
else
def #{symbol}(*args)
- #{memoized_ivar} ||= {}
+ #{memoized_ivar} ||= {} unless frozen?
reload = args.pop if args.last == true || args.last == :reload
- if !reload && #{memoized_ivar} && #{memoized_ivar}.has_key?(args)
- #{memoized_ivar}[args]
+ if #{memoized_ivar}
+ if !reload && #{memoized_ivar}.has_key?(args)
+ #{memoized_ivar}[args]
+ elsif #{memoized_ivar}
+ #{memoized_ivar}[args] = #{original_method}(*args)
+ end
else
- #{memoized_ivar}[args] = #{original_method}(*args)
+ #{original_method}(*args)
end
end
end
@@ -119,6 +119,21 @@ def test_reloadable
assert_equal 3, @calculator.counter
end
+ def test_unmemoize_all
+ assert_equal 1, @calculator.counter
+
+ assert @calculator.instance_variable_get(:@_memoized_counter).any?
+ @calculator.unmemoize_all
+ assert @calculator.instance_variable_get(:@_memoized_counter).empty?
+
+ assert_equal 2, @calculator.counter
+ end
+
+ def test_memoize_all
+ @calculator.memoize_all
+ assert @calculator.instance_variable_defined?(:@_memoized_counter)
+ end
+
def test_memoization_cache_is_different_for_each_instance
assert_equal 1, @calculator.counter
assert_equal 2, @calculator.counter(:reload)

0 comments on commit 3fc9a67

Please sign in to comment.