public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
memoize_ and unmemoize_all
jeremy (author)
Wed Aug 13 17:22:38 -0700 2008
commit  3fc9a67c04bade858e7ac7eb8cd94eec6a63ec27
tree    dc03084bc85e646542441b8d132472ed8a3a797f
parent  3284fbb86629f398ba2634dd9369bc65beb7d6ae
...
10
11
12
13
14
15
16
17
18
19
 
 
 
 
 
 
 
 
 
 
 
 
20
21
22
 
23
24
 
 
 
 
 
 
 
25
26
27
28
29
30
31
 
 
32
33
34
...
38
39
40
41
42
43
44
 
 
45
 
46
47
48
49
 
50
51
52
53
 
 
 
 
 
 
54
55
 
56
57
58
...
10
11
12
 
 
 
 
 
 
 
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
30
31
32
33
34
35
36
37
38
39
40
41
 
 
42
43
44
45
46
...
50
51
52
 
 
 
 
53
54
55
56
57
58
59
 
60
61
62
 
 
63
64
65
66
67
68
69
 
70
71
72
73
0
@@ -10,25 +10,37 @@ module ActiveSupport
0
       end
0
 
0
       def freeze_with_memoizable
0
-        unless frozen?
0
-          methods.each do |method|
0
-            if method.to_s =~ /^_unmemoized_(.*)/
0
-              begin
0
-                __send__($1).freeze
0
-              rescue ArgumentError
0
-              end
0
+        memoize_all unless frozen?
0
+        freeze_without_memoizable
0
+      end
0
+
0
+      def memoize_all
0
+        methods.each do |m|
0
+          if m.to_s =~ /^_unmemoized_(.*)/
0
+            if method(m).arity == 0
0
+              __send__($1)
0
+            else
0
+              ivar = :"@_memoized_#{$1}"
0
+              instance_variable_set(ivar, {})
0
             end
0
           end
0
         end
0
+      end
0
 
0
-        freeze_without_memoizable
0
+      def unmemoize_all
0
+        methods.each do |m|
0
+          if m.to_s =~ /^_unmemoized_(.*)/
0
+            ivar = :"@_memoized_#{$1}"
0
+            instance_variable_get(ivar).clear if instance_variable_defined?(ivar)
0
+          end
0
+        end
0
       end
0
     end
0
 
0
     def memoize(*symbols)
0
       symbols.each do |symbol|
0
-        original_method = "_unmemoized_#{symbol}"
0
-        memoized_ivar = "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}"
0
+        original_method = :"_unmemoized_#{symbol}"
0
+        memoized_ivar = :"@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}"
0
 
0
         class_eval <<-EOS, __FILE__, __LINE__
0
           include Freezable
0
@@ -38,21 +50,24 @@ module ActiveSupport
0
 
0
           if instance_method(:#{symbol}).arity == 0
0
             def #{symbol}(reload = false)
0
-              if !reload && defined? #{memoized_ivar}
0
-                #{memoized_ivar}
0
-              else
0
-                #{memoized_ivar} = #{original_method}
0
+              if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty?
0
+                #{memoized_ivar} = [#{original_method}]
0
               end
0
+              #{memoized_ivar}[0]
0
             end
0
           else
0
             def #{symbol}(*args)
0
-              #{memoized_ivar} ||= {}
0
+              #{memoized_ivar} ||= {} unless frozen?
0
               reload = args.pop if args.last == true || args.last == :reload
0
 
0
-              if !reload && #{memoized_ivar} && #{memoized_ivar}.has_key?(args)
0
-                #{memoized_ivar}[args]
0
+              if #{memoized_ivar}
0
+                if !reload && #{memoized_ivar}.has_key?(args)
0
+                  #{memoized_ivar}[args]
0
+                elsif #{memoized_ivar}
0
+                  #{memoized_ivar}[args] = #{original_method}(*args)
0
+                end
0
               else
0
-                #{memoized_ivar}[args] = #{original_method}(*args)
0
+                #{original_method}(*args)
0
               end
0
             end
0
           end
...
119
120
121
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
123
124
...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
0
@@ -119,6 +119,21 @@ uses_mocha 'Memoizable' do
0
       assert_equal 3, @calculator.counter
0
     end
0
 
0
+    def test_unmemoize_all
0
+      assert_equal 1, @calculator.counter
0
+
0
+      assert @calculator.instance_variable_get(:@_memoized_counter).any?
0
+      @calculator.unmemoize_all
0
+      assert @calculator.instance_variable_get(:@_memoized_counter).empty?
0
+
0
+      assert_equal 2, @calculator.counter
0
+    end
0
+
0
+    def test_memoize_all
0
+      @calculator.memoize_all
0
+      assert @calculator.instance_variable_defined?(:@_memoized_counter)
0
+    end
0
+
0
     def test_memoization_cache_is_different_for_each_instance
0
       assert_equal 1, @calculator.counter
0
       assert_equal 2, @calculator.counter(:reload)

Comments