aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorJoshua Peek <josh@joshpeek.com>2008-07-18 15:32:28 -0500
committerJoshua Peek <josh@joshpeek.com>2008-07-18 15:32:28 -0500
commitef6f6625c91ea789a033799f649e4388e4a71045 (patch)
tree3202088506d3da2076b8704d17dca3d4a1f7a329 /activesupport
parente1f23da53cef20a60e4bf458d959fe2bfe7d52ea (diff)
downloadrails-ef6f6625c91ea789a033799f649e4388e4a71045.tar.gz
rails-ef6f6625c91ea789a033799f649e4388e4a71045.tar.bz2
rails-ef6f6625c91ea789a033799f649e4388e4a71045.zip
Changed ActiveSupport::Memoizable API to extend since it mainly adds the memoize class method
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/lib/active_support/memoizable.rb55
-rw-r--r--activesupport/test/memoizable_test.rb42
2 files changed, 63 insertions, 34 deletions
diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb
index c41feef4c7..59fecbecb1 100644
--- a/activesupport/lib/active_support/memoizable.rb
+++ b/activesupport/lib/active_support/memoizable.rb
@@ -1,37 +1,38 @@
module ActiveSupport
- module Memoizable
- def self.included(base) #:nodoc:
- base.extend(ClassMethods)
- end
-
- module ClassMethods
- def memoize(*symbols)
- symbols.each do |symbol|
- original_method = "unmemoized_#{symbol}"
- memoized_ivar = "@#{symbol}"
- raise "Already memoized #{symbol}" if instance_methods.map(&:to_s).include?(original_method)
-
- alias_method original_method, symbol
- class_eval <<-EOS, __FILE__, __LINE__
- def #{symbol}(reload = false)
- if !reload && defined? #{memoized_ivar}
- #{memoized_ivar}
- else
- #{memoized_ivar} = #{original_method}.freeze
- end
+ module Memoizable #:nodoc:
+ def self.extended(obj)
+ klass = obj.respond_to?(:class_eval) ? obj : obj.metaclass
+ klass.class_eval do
+ def freeze
+ methods.each do |method|
+ if m = method.to_s.match(/^unmemoized_(.*)/)
+ send(m[1])
end
- EOS
+ end
+ super
end
end
end
- def freeze
- methods.each do |method|
- if m = method.to_s.match(/\Aunmemoized_(.*)/)
- send(m[1])
- end
+ def memoize(*symbols)
+ symbols.each do |symbol|
+ original_method = "unmemoized_#{symbol}"
+ memoized_ivar = "@#{symbol}"
+
+ klass = respond_to?(:class_eval) ? self : self.metaclass
+ raise "Already memoized #{symbol}" if klass.instance_methods.map(&:to_s).include?(original_method)
+
+ klass.class_eval <<-EOS, __FILE__, __LINE__
+ alias_method :#{original_method}, :#{symbol}
+ def #{symbol}(reload = false)
+ if !reload && defined? #{memoized_ivar}
+ #{memoized_ivar}
+ else
+ #{memoized_ivar} = #{original_method}.freeze
+ end
+ end
+ EOS
end
- super
end
end
end
diff --git a/activesupport/test/memoizable_test.rb b/activesupport/test/memoizable_test.rb
index b649b31455..79769631ad 100644
--- a/activesupport/test/memoizable_test.rb
+++ b/activesupport/test/memoizable_test.rb
@@ -3,21 +3,24 @@ require 'abstract_unit'
uses_mocha 'Memoizable' do
class MemoizableTest < Test::Unit::TestCase
class Person
- include ActiveSupport::Memoizable
+ extend ActiveSupport::Memoizable
def name
fetch_name_from_floppy
end
+ memoize :name
+
def age
nil
end
- def random
- rand(0)
+ def counter
+ @counter ||= 0
+ @counter += 1
end
- memoize :name, :age, :random
+ memoize :age, :counter
private
def fetch_name_from_floppy
@@ -37,9 +40,9 @@ uses_mocha 'Memoizable' do
end
def test_reloadable
- random = @person.random
- assert_equal random, @person.random
- assert_not_equal random, @person.random(:reload)
+ counter = @person.counter
+ assert_equal 1, @person.counter
+ assert_equal 2, @person.counter(:reload)
end
def test_memoized_methods_are_frozen
@@ -58,5 +61,30 @@ uses_mocha 'Memoizable' do
def test_double_memoization
assert_raise(RuntimeError) { Person.memoize :name }
end
+
+ class Company
+ def name
+ lookup_name
+ end
+
+ def lookup_name
+ "37signals"
+ end
+ end
+
+ def test_object_memoization
+ company = Company.new
+ company.extend ActiveSupport::Memoizable
+ company.memoize :name
+
+ assert_equal "37signals", company.name
+ # Mocha doesn't play well with frozen objects
+ company.metaclass.instance_eval { define_method(:lookup_name) { b00m } }
+ assert_equal "37signals", company.name
+
+ assert_equal true, company.name.frozen?
+ company.freeze
+ assert_equal true, company.name.frozen?
+ end
end
end