From 0056e5aafb098ebece8616d786d7a6c1ec7a0288 Mon Sep 17 00:00:00 2001 From: Jay Pignata Date: Mon, 28 Sep 2009 00:40:54 -0400 Subject: [PATCH] Add options hash to memoize This change will allow a :force option to be passed to memoize that will allow an already memoized method to be re-memoized. This is useful in scenarios such as inheritance where a method is overridden but cannot be memoized as its ancestor has left remnants of itself in the class --- activesupport/lib/active_support/memoizable.rb | 19 +++++++++++++------ activesupport/test/memoizable_test.rb | 13 +++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb index b197fbc..4b8d993 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -19,7 +19,7 @@ module ActiveSupport def self.memoized_ivar_for(symbol) "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}".to_sym end - + module InstanceMethods def self.included(base) base.class_eval do @@ -69,17 +69,24 @@ module ActiveSupport end end - def memoize(*symbols) - symbols.each do |symbol| + def memoize(*args) + options = args.pop if args.last.is_a? Hash + + args.each do |symbol| original_method = :"_unmemoized_#{symbol}" memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol) + unless options && options[:force] + class_eval <<-EOS, __FILE__, __LINE__ + 1 + if method_defined?(:#{original_method}) # if method_defined?(:_unmemoized_mime_type) + raise "Already memoized #{symbol}" # raise "Already memoized mime_type" + end # end + EOS + end + class_eval <<-EOS, __FILE__, __LINE__ + 1 include InstanceMethods # include InstanceMethods # - if method_defined?(:#{original_method}) # if method_defined?(:_unmemoized_mime_type) - raise "Already memoized #{symbol}" # raise "Already memoized mime_type" - end # end alias #{original_method} #{symbol} # alias _unmemoized_mime_type mime_type # if instance_method(:#{symbol}).arity == 0 # if instance_method(:mime_type).arity == 0 diff --git a/activesupport/test/memoizable_test.rb b/activesupport/test/memoizable_test.rb index 195e3ea..0e8d686 100644 --- a/activesupport/test/memoizable_test.rb +++ b/activesupport/test/memoizable_test.rb @@ -44,6 +44,12 @@ class MemoizableTest < ActiveSupport::TestCase end memoize :is_developer? end + + class Employee < Person + def name + "John" + end + end class Company attr_reader :name_calls @@ -248,4 +254,11 @@ class MemoizableTest < ActiveSupport::TestCase assert_equal 1, person.is_developer_calls end + def test_overridden_method_memoization + employee = Employee.new + employee.extend ActiveSupport::Memoizable + assert_nothing_raised { employee.memoize :name, :force => true } + assert_equal "John", employee.name + end + end -- 1.6.4.2