diff options
author | Joshua Peek <josh@joshpeek.com> | 2008-07-14 19:50:32 -0500 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2008-07-14 19:50:32 -0500 |
commit | 8a9934a9d9fc98b56c4566ae2e3fd4d83e505d3e (patch) | |
tree | fe7ed2626140178c722f5245d37b23c311da5ce4 | |
parent | d27dd860c7f4f9b9e5aebe7d0c6e9b6108d8717c (diff) | |
download | rails-8a9934a9d9fc98b56c4566ae2e3fd4d83e505d3e.tar.gz rails-8a9934a9d9fc98b56c4566ae2e3fd4d83e505d3e.tar.bz2 rails-8a9934a9d9fc98b56c4566ae2e3fd4d83e505d3e.zip |
Added Memoizable mixin for caching simple lazy loaded attributes
-rw-r--r-- | activesupport/CHANGELOG | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support.rb | 1 | ||||
-rw-r--r-- | activesupport/lib/active_support/memoizable.rb | 32 | ||||
-rw-r--r-- | activesupport/test/memoizable_test.rb | 45 |
4 files changed, 80 insertions, 0 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 983e7d0dac..0c308a1cfe 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Added Memoizable mixin for caching simple lazy loaded attributes [Josh Peek] + * Move the test related core_ext stuff out of core_ext so it's only loaded by the test helpers. [Michael Koziarski] * Add Inflection rules for String#humanize. #535 [dcmanges] diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index 1a8603e892..0526057b15 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -43,6 +43,7 @@ require 'active_support/ordered_hash' require 'active_support/ordered_options' require 'active_support/option_merger' +require 'active_support/memoizable' require 'active_support/string_inquirer' require 'active_support/values/time_zone' diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb new file mode 100644 index 0000000000..c78fb0a793 --- /dev/null +++ b/activesupport/lib/active_support/memoizable.rb @@ -0,0 +1,32 @@ +module ActiveSupport + module Memoizable + def self.included(base) #:nodoc: + base.extend(ClassMethods) + end + + module ClassMethods + def memorize(symbol) + original_method = "_unmemorized_#{symbol}" + alias_method original_method, symbol + class_eval <<-EOS, __FILE__, __LINE__ + def #{symbol} + if instance_variable_defined?(:@#{symbol}) + @#{symbol} + else + @#{symbol} = #{original_method} + end + end + EOS + end + end + + def freeze + methods.each do |method| + if m = method.to_s.match(/^_unmemorized_(.*)/) + send(m[1]).freeze + end + end + super + end + end +end diff --git a/activesupport/test/memoizable_test.rb b/activesupport/test/memoizable_test.rb new file mode 100644 index 0000000000..40a02cf253 --- /dev/null +++ b/activesupport/test/memoizable_test.rb @@ -0,0 +1,45 @@ +require 'abstract_unit' + +uses_mocha 'Memoizable' do + class MemoizableTest < Test::Unit::TestCase + class Person + include ActiveSupport::Memoizable + + def name + fetch_name_from_floppy + end + memorize :name + + def age + nil + end + memorize :age + + private + def fetch_name_from_floppy + "Josh" + end + end + + def test_memoization + person = Person.new + assert_equal "Josh", person.name + + person.expects(:fetch_name_from_floppy).never + 2.times { assert_equal "Josh", person.name } + end + + def test_memoized_methods_are_frozen + person = Person.new + person.freeze + assert_equal "Josh", person.name + assert_equal true, person.name.frozen? + end + + def test_memoization_frozen_with_nil_value + person = Person.new + person.freeze + assert_equal nil, person.age + end + end +end |