diff options
author | Joshua Peek <josh@joshpeek.com> | 2008-07-22 10:26:44 -0500 |
---|---|---|
committer | Joshua Peek <josh@joshpeek.com> | 2008-07-22 10:26:44 -0500 |
commit | 8a87d8a6c2c6dfb423bcaf61c750010d80993b16 (patch) | |
tree | 16c43dd83a34f451bc0dbddbd7167ce78ffed351 /activesupport/lib | |
parent | 8b858782fa693e89a47fc3dd5ae38d842ede6d04 (diff) | |
download | rails-8a87d8a6c2c6dfb423bcaf61c750010d80993b16.tar.gz rails-8a87d8a6c2c6dfb423bcaf61c750010d80993b16.tar.bz2 rails-8a87d8a6c2c6dfb423bcaf61c750010d80993b16.zip |
Improved Memoizable test coverage and added support for multiple arguments
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/core_ext/object/metaclass.rb | 5 | ||||
-rw-r--r-- | activesupport/lib/active_support/memoizable.rb | 55 |
2 files changed, 38 insertions, 22 deletions
diff --git a/activesupport/lib/active_support/core_ext/object/metaclass.rb b/activesupport/lib/active_support/core_ext/object/metaclass.rb index 169a76dfb7..93fb0ad594 100644 --- a/activesupport/lib/active_support/core_ext/object/metaclass.rb +++ b/activesupport/lib/active_support/core_ext/object/metaclass.rb @@ -5,4 +5,9 @@ class Object self end end + + # If class_eval is called on an object, add those methods to its metaclass + def class_eval(*args, &block) + metaclass.class_eval(*args, &block) + end end diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb index f7cd73d39c..21636b8af4 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -1,32 +1,43 @@ module ActiveSupport - module Memoizable #:nodoc: + module Memoizable + module Freezable + def self.included(base) + base.class_eval do + unless base.method_defined?(:freeze_without_memoizable) + alias_method_chain :freeze, :memoizable + end + end + end + + def freeze_with_memoizable + methods.each do |method| + if m = method.to_s.match(/^_unmemoized_(.*)/) + send(m[1]) + end + end + freeze_without_memoizable + end + end + def memoize(*symbols) symbols.each do |symbol| - original_method = "unmemoized_#{symbol}" - memoized_ivar = "@#{symbol}" + original_method = "_unmemoized_#{symbol}" + memoized_ivar = "@_memoized_#{symbol}" - klass = respond_to?(:class_eval) ? self : self.metaclass - raise "Already memoized #{symbol}" if klass.instance_methods.map(&:to_s).include?(original_method) + class_eval <<-EOS, __FILE__, __LINE__ + include Freezable - klass.class_eval <<-EOS, __FILE__, __LINE__ - unless instance_methods.map(&:to_s).include?("freeze_without_memoizable") - alias_method :freeze_without_memoizable, :freeze - def freeze - methods.each do |method| - if m = method.to_s.match(/^unmemoized_(.*)/) - send(m[1]) - end - end - freeze_without_memoizable - end - end + raise "Already memoized #{symbol}" if method_defined?(:#{original_method}) + alias #{original_method} #{symbol} + + def #{symbol}(*args) + #{memoized_ivar} ||= {} + reload = args.pop if args.last == true || args.last == :reload - alias_method :#{original_method}, :#{symbol} - def #{symbol}(reload = false) - if !reload && defined? #{memoized_ivar} - #{memoized_ivar} + if !reload && #{memoized_ivar} && #{memoized_ivar}.has_key?(args) + #{memoized_ivar}[args] else - #{memoized_ivar} = #{original_method}.freeze + #{memoized_ivar}[args] = #{original_method}(*args).freeze end end EOS |