From 35fe922d427fabcbb2947dba225c8b8a7f2801da Mon Sep 17 00:00:00 2001 From: Matthew Rudy Jacobs Date: Wed, 7 Dec 2011 12:19:33 +0800 Subject: [PATCH] Memoizable no longer ActiveSupport::Memoizable no dependency on ActiveSupport. --- lib/core_ext/singleton_class.rb | 13 +++ lib/memoizable.rb | 175 ++++++++++++++++---------------- test/memoizable_test.rb | 14 +-- test/test_helper.rb | 1 - 4 files changed, 107 insertions(+), 96 deletions(-) create mode 100644 lib/core_ext/singleton_class.rb diff --git a/lib/core_ext/singleton_class.rb b/lib/core_ext/singleton_class.rb new file mode 100644 index 0000000..6d6cc3d --- /dev/null +++ b/lib/core_ext/singleton_class.rb @@ -0,0 +1,13 @@ +module Kernel + # Returns the object's singleton class. + def singleton_class + class << self + self + end + end unless respond_to?(:singleton_class) # exists in 1.9.2 + + # class_eval on an object acts like singleton_class.class_eval. + def class_eval(*args, &block) + singleton_class.class_eval(*args, &block) + end +end \ No newline at end of file diff --git a/lib/memoizable.rb b/lib/memoizable.rb index 644f7fe..e2a66d2 100644 --- a/lib/memoizable.rb +++ b/lib/memoizable.rb @@ -1,110 +1,109 @@ -require 'active_support/core_ext/kernel/singleton_class' -require 'active_support/core_ext/module/aliasing' +# require 'active_support/core_ext/kernel/singleton_class' +require 'core_ext/singleton_class' -module ActiveSupport - module Memoizable +module Memoizable - def self.memoized_ivar_for(symbol) - "@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}".to_sym - end + 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 - unless base.method_defined?(:freeze_without_memoizable) - alias_method_chain :freeze, :memoizable - end + module InstanceMethods + def self.included(base) + base.class_eval do + unless base.method_defined?(:freeze_without_memoizable) + alias_method :freeze_without_memoizable, :freeze + alias_method :freeze, :freeze_with_memoizable end end + end - def freeze_with_memoizable - memoize_all unless frozen? - freeze_without_memoizable - end + def freeze_with_memoizable + memoize_all unless frozen? + freeze_without_memoizable + end - def memoize_all - prime_cache ".*" - end + def memoize_all + prime_cache ".*" + end - def unmemoize_all - flush_cache ".*" - end + def unmemoize_all + flush_cache ".*" + end - def prime_cache(*syms) - syms.each do |sym| - methods.each do |m| - if m.to_s =~ /^_unmemoized_(#{sym})/ - if method(m).arity == 0 - __send__($1) - else - ivar = ActiveSupport::Memoizable.memoized_ivar_for($1) - instance_variable_set(ivar, {}) - end + def prime_cache(*syms) + syms.each do |sym| + methods.each do |m| + if m.to_s =~ /^_unmemoized_(#{sym})/ + if method(m).arity == 0 + __send__($1) + else + ivar = Memoizable.memoized_ivar_for($1) + instance_variable_set(ivar, {}) end end end end + end - def flush_cache(*syms) - syms.each do |sym| - (methods + private_methods + protected_methods).each do |m| - if m.to_s =~ /^_unmemoized_(#{sym.to_s.gsub(/\?\Z/, '\?')})/ - ivar = ActiveSupport::Memoizable.memoized_ivar_for($1) - instance_variable_get(ivar).clear if instance_variable_defined?(ivar) - end + def flush_cache(*syms) + syms.each do |sym| + (methods + private_methods + protected_methods).each do |m| + if m.to_s =~ /^_unmemoized_(#{sym.to_s.gsub(/\?\Z/, '\?')})/ + ivar = Memoizable.memoized_ivar_for($1) + instance_variable_get(ivar).clear if instance_variable_defined?(ivar) end end end end + end - def memoize(*symbols) - symbols.each do |symbol| - original_method = :"_unmemoized_#{symbol}" - memoized_ivar = ActiveSupport::Memoizable.memoized_ivar_for(symbol) + def memoize(*symbols) + symbols.each do |symbol| + original_method = :"_unmemoized_#{symbol}" + memoized_ivar = Memoizable.memoized_ivar_for(symbol) - 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 - def #{symbol}(reload = false) # def mime_type(reload = false) - if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? # if reload || !defined?(@_memoized_mime_type) || @_memoized_mime_type.empty? - #{memoized_ivar} = [#{original_method}] # @_memoized_mime_type = [_unmemoized_mime_type] - end # end - #{memoized_ivar}[0] # @_memoized_mime_type[0] - end # end - else # else - def #{symbol}(*args) # def mime_type(*args) - #{memoized_ivar} ||= {} unless frozen? # @_memoized_mime_type ||= {} unless frozen? - args_length = method(:#{original_method}).arity # args_length = method(:_unmemoized_mime_type).arity - if args.length == args_length + 1 && # if args.length == args_length + 1 && - (args.last == true || args.last == :reload) # (args.last == true || args.last == :reload) - reload = args.pop # reload = args.pop - end # end - # - if defined?(#{memoized_ivar}) && #{memoized_ivar} # if defined?(@_memoized_mime_type) && @_memoized_mime_type - if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args) - #{memoized_ivar}[args] # @_memoized_mime_type[args] - elsif #{memoized_ivar} # elsif @_memoized_mime_type - #{memoized_ivar}[args] = #{original_method}(*args) # @_memoized_mime_type[args] = _unmemoized_mime_type(*args) - end # end - else # else - #{original_method}(*args) # _unmemoized_mime_type(*args) - end # end - end # end - end # end - # - if private_method_defined?(#{original_method.inspect}) # if private_method_defined?(:_unmemoized_mime_type) - private #{symbol.inspect} # private :mime_type - elsif protected_method_defined?(#{original_method.inspect}) # elsif protected_method_defined?(:_unmemoized_mime_type) - protected #{symbol.inspect} # protected :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 + def #{symbol}(reload = false) # def mime_type(reload = false) + if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? # if reload || !defined?(@_memoized_mime_type) || @_memoized_mime_type.empty? + #{memoized_ivar} = [#{original_method}] # @_memoized_mime_type = [_unmemoized_mime_type] + end # end + #{memoized_ivar}[0] # @_memoized_mime_type[0] + end # end + else # else + def #{symbol}(*args) # def mime_type(*args) + #{memoized_ivar} ||= {} unless frozen? # @_memoized_mime_type ||= {} unless frozen? + args_length = method(:#{original_method}).arity # args_length = method(:_unmemoized_mime_type).arity + if args.length == args_length + 1 && # if args.length == args_length + 1 && + (args.last == true || args.last == :reload) # (args.last == true || args.last == :reload) + reload = args.pop # reload = args.pop + end # end + # + if defined?(#{memoized_ivar}) && #{memoized_ivar} # if defined?(@_memoized_mime_type) && @_memoized_mime_type + if !reload && #{memoized_ivar}.has_key?(args) # if !reload && @_memoized_mime_type.has_key?(args) + #{memoized_ivar}[args] # @_memoized_mime_type[args] + elsif #{memoized_ivar} # elsif @_memoized_mime_type + #{memoized_ivar}[args] = #{original_method}(*args) # @_memoized_mime_type[args] = _unmemoized_mime_type(*args) + end # end + else # else + #{original_method}(*args) # _unmemoized_mime_type(*args) + end # end + end # end + end # end + # + if private_method_defined?(#{original_method.inspect}) # if private_method_defined?(:_unmemoized_mime_type) + private #{symbol.inspect} # private :mime_type + elsif protected_method_defined?(#{original_method.inspect}) # elsif protected_method_defined?(:_unmemoized_mime_type) + protected #{symbol.inspect} # protected :mime_type + end # end + EOS end end -end \ No newline at end of file +end diff --git a/test/memoizable_test.rb b/test/memoizable_test.rb index 613860e..f5e55af 100644 --- a/test/memoizable_test.rb +++ b/test/memoizable_test.rb @@ -1,9 +1,9 @@ require 'test_helper' require 'memoizable' -class MemoizableTest < ActiveSupport::TestCase +class MemoizableTest < Test::Unit::TestCase class Person - extend ActiveSupport::Memoizable + extend Memoizable attr_reader :name_calls, :age_calls, :is_developer_calls, :name_query_calls @@ -66,7 +66,7 @@ def name end module Rates - extend ActiveSupport::Memoizable + extend Memoizable attr_reader :sales_tax_calls def sales_tax(price) @@ -78,7 +78,7 @@ def sales_tax(price) end class Calculator - extend ActiveSupport::Memoizable + extend Memoizable include Rates attr_reader :fib_calls @@ -216,7 +216,7 @@ def test_memoization_with_boolean_arg def test_object_memoization [Company.new, Company.new, Company.new].each do |company| - company.extend ActiveSupport::Memoizable + company.extend Memoizable company.memoize :name assert_equal "37signals", company.name @@ -250,11 +250,11 @@ def test_object_memoized_module_methods def test_double_memoization assert_raise(RuntimeError) { Person.memoize :name } person = Person.new - person.extend ActiveSupport::Memoizable + person.extend Memoizable assert_raise(RuntimeError) { person.memoize :name } company = Company.new - company.extend ActiveSupport::Memoizable + company.extend Memoizable company.memoize :name assert_raise(RuntimeError) { company.memoize :name } end diff --git a/test/test_helper.rb b/test/test_helper.rb index 7069589..f7ef3d1 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,5 +1,4 @@ require 'rubygems' require 'test/unit' -require 'active_support' $:.unshift File.expand_path(File.dirname(__FILE__)+"/../lib")