From 90a9a7013ca733c6414d8ec6ababae2c65ad7c99 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 18 Jun 2008 15:55:32 -0700 Subject: Write benchmark output to separate files per test+metric. Support Lloyd Hilaiel's GC.heap_info patch for current heap size. --- .../lib/active_support/testing/performance.rb | 40 +++++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index 24936029a2..9f85bca716 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -97,6 +97,11 @@ module ActiveSupport rate = @total / profile_options[:runs] '%20s: %s/run' % [@metric.name, @metric.format(rate)] end + + protected + def output_filename + "#{profile_options[:output]}/#{full_test_name}" + end end class Benchmarker < Performer @@ -107,9 +112,9 @@ module ActiveSupport def record avg = @metric.total / profile_options[:runs].to_i - data = [full_test_name, @metric.name, avg, Time.now.utc.xmlschema] * ',' + now = Time.now.utc.xmlschema with_output_file do |file| - file.puts "#{data},#{environment}" + file.puts "#{avg},#{now},#{environment}" end end @@ -134,10 +139,10 @@ module ActiveSupport end protected - HEADER = 'test,metric,measurement,created_at,app,rails,ruby,platform' + HEADER = 'measurement,created_at,app,rails,ruby,platform' def with_output_file - fname = "#{profile_options[:output]}/benchmarks.csv" + fname = output_filename if new = !File.exist?(fname) FileUtils.mkdir_p(File.dirname(fname)) @@ -148,6 +153,10 @@ module ActiveSupport yield file end end + + def output_filename + "#{super}.csv" + end end class Profiler < Performer @@ -183,7 +192,7 @@ module ActiveSupport else printer_class.name.sub(/Printer$/, '').underscore end - "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}_#{suffix}" + "#{super()}_#{suffix}" end end @@ -287,18 +296,35 @@ module ActiveSupport class Memory < Base Mode = RubyProf::MEMORY + # ruby-prof wrapper if RubyProf.respond_to?(:measure_memory) def measure RubyProf.measure_memory / 1024.0 end + + # Ruby 1.8 + adymo patch elsif GC.respond_to?(:allocated_size) def measure GC.allocated_size / 1024.0 end + + # Ruby 1.8 + lloyd patch + elsif GC.respond_to?(:heap_info) + def measure + GC.heap_info['heap_current_memory'] / 1024.0 + end + + # Ruby 1.9 unpatched elsif GC.respond_to?(:malloc_allocated_size) def measure GC.malloc_allocated_size / 1024.0 end + + # Unavailable + else + def measure + 0 + end end def format(measurement) @@ -317,6 +343,10 @@ module ActiveSupport def measure ObjectSpace.allocated_objects end + else + def measure + 0 + end end def format(measurement) -- cgit v1.2.3 From 616bc42fd7675a42e8bd461855385d9a2b0cf5e3 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 18 Jun 2008 18:34:25 -0700 Subject: Performance: tweak unsupported metric error message --- activesupport/lib/active_support/testing/performance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index 9f85bca716..ee09b301ba 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -44,7 +44,7 @@ module ActiveSupport run_profile(klass.new) result.add_run else - $stderr.puts "Skipping unknown metric #{metric_name.inspect}. Expected :process_time, :wall_time, :cpu_time, :memory, or :objects." + $stderr.puts '%20s: unsupported' % metric_name.to_s end end -- cgit v1.2.3 From 2541f7ac478e00d2a225399d1619ccf6c33f2d9c Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 18 Jun 2008 18:36:04 -0700 Subject: Oops, include metric name in csv filename --- activesupport/lib/active_support/testing/performance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index ee09b301ba..728fa860cb 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -100,7 +100,7 @@ module ActiveSupport protected def output_filename - "#{profile_options[:output]}/#{full_test_name}" + "#{profile_options[:output]}/#{full_test_name}_#{@metric.name}" end end -- cgit v1.2.3 From 1e0d2e36cc4b524ca5a4330eeb3e3fd7f5ca0b5e Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 18 Jun 2008 18:46:17 -0700 Subject: Performance: add GC metrics for # of runs and total runtime --- .../lib/active_support/testing/performance.rb | 58 ++++++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index 728fa860cb..2317171467 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -12,13 +12,13 @@ module ActiveSupport if benchmark = ARGV.include?('--benchmark') # HAX for rake test { :benchmark => true, :runs => 10, - :metrics => [:process_time, :memory, :objects], + :metrics => [:process_time, :memory, :objects, :gc_runs, :gc_time], :output => 'tmp/performance' } else { :benchmark => false, :runs => 1, :min_percent => 0.02, - :metrics => [:wall_time, :memory, :objects], + :metrics => [:process_time, :memory, :objects, :gc_runs, :gc_time], :formats => [:flat, :graph_html, :call_tree], :output => 'tmp/performance' } end @@ -72,9 +72,13 @@ module ActiveSupport protected def run_warmup + 5.times { GC.start } + time = Metrics::Time.new run_test(time, :benchmark) puts "%s (%s warmup)" % [full_test_name, time.format(time.total)] + + 5.times { GC.start } end def run_profile(metric) @@ -219,6 +223,10 @@ module ActiveSupport self.class::Mode end + def measure + 0 + end + def benchmark with_gc_stats do before = measure @@ -319,12 +327,6 @@ module ActiveSupport def measure GC.malloc_allocated_size / 1024.0 end - - # Unavailable - else - def measure - 0 - end end def format(measurement) @@ -343,9 +345,27 @@ module ActiveSupport def measure ObjectSpace.allocated_objects end - else + end + + def format(measurement) + measurement.to_i.to_s + end + end + + class GcRuns < Base + Mode = RubyProf::GC_RUNS + + if RubyProf.respond_to?(:measure_gc_runs) + def measure + RubyProf.measure_gc_runs + end + elsif GC.respond_to?(:collections) def measure - 0 + GC.collections + end + elsif GC.respond_to?(:heap_info) + def measure + GC.heap_info['num_gc_passes'] end end @@ -353,6 +373,24 @@ module ActiveSupport measurement.to_i.to_s end end + + class GcTime < Base + Mode = RubyProf::GC_TIME + + if RubyProf.respond_to?(:measure_gc_time) + def measure + RubyProf.measure_gc_time + end + elsif GC.respond_to?(:time) + def measure + GC.time + end + end + + def format(measurement) + '%d ms' % (measurement / 1000) + end + end end end end -- cgit v1.2.3 From f47c81ff37afb5e5340b6f2cb47a5bb76b94f5c0 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 20 Jun 2008 00:25:41 -0700 Subject: Fall back to #to_s for cache key expansion --- activesupport/lib/active_support/cache.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 2f1143e610..b8ccd35753 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -19,7 +19,7 @@ module ActiveSupport def self.expand_cache_key(key, namespace = nil) expanded_cache_key = namespace ? "#{namespace}/" : "" - + if ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"] expanded_cache_key << "#{ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]}/" end @@ -31,6 +31,8 @@ module ActiveSupport key.collect { |element| expand_cache_key(element) }.to_param when key.respond_to?(:to_param) key.to_param + else + key.to_s end expanded_cache_key -- cgit v1.2.3 From 83c3e9903d2ad76ef4aea1d64d6514443f6ad438 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 20 Jun 2008 00:35:11 -0700 Subject: Don't profile GC runs/time by default --- activesupport/lib/active_support/testing/performance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index 2317171467..cadcb155c1 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -18,7 +18,7 @@ module ActiveSupport { :benchmark => false, :runs => 1, :min_percent => 0.02, - :metrics => [:process_time, :memory, :objects, :gc_runs, :gc_time], + :metrics => [:process_time, :memory, :objects], :formats => [:flat, :graph_html, :call_tree], :output => 'tmp/performance' } end -- cgit v1.2.3 From 879245de1ce294e8951927f0e694333746772187 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 20 Jun 2008 00:36:59 -0700 Subject: Tired of seeing /run --- activesupport/lib/active_support/testing/performance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index cadcb155c1..1f8a5eec8f 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -99,7 +99,7 @@ module ActiveSupport def report rate = @total / profile_options[:runs] - '%20s: %s/run' % [@metric.name, @metric.format(rate)] + '%20s: %s' % [@metric.name, @metric.format(rate)] end protected -- cgit v1.2.3 From 00ba4c0cf32f9417d47bd891eba97f2e04609520 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 20 Jun 2008 00:46:00 -0700 Subject: true#to_param => true, so be sure to #to_s expanded cache keys --- activesupport/lib/active_support/cache.rb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index b8ccd35753..27beff9815 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -25,15 +25,15 @@ module ActiveSupport end expanded_cache_key << case - when key.respond_to?(:cache_key) - key.cache_key - when key.is_a?(Array) - key.collect { |element| expand_cache_key(element) }.to_param - when key.respond_to?(:to_param) - key.to_param - else - key.to_s - end + when key.respond_to?(:cache_key) + key.cache_key + when key.is_a?(Array) + key.collect { |element| expand_cache_key(element) }.to_param + when key.respond_to?(:to_param) + key.to_param + else + key + end.to_s expanded_cache_key end -- cgit v1.2.3 From 161ab28b7c0bd28828b6d18613a9de09d47023c6 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Jun 2008 11:31:06 -0500 Subject: Added block-handling to Enumerable#many? (Damian Janowski) [#452 state:resolved] --- activesupport/lib/active_support/core_ext/enumerable.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb index 9647797ec2..e451e9933a 100644 --- a/activesupport/lib/active_support/core_ext/enumerable.rb +++ b/activesupport/lib/active_support/core_ext/enumerable.rb @@ -79,7 +79,9 @@ module Enumerable end # Returns true if the collection has more than 1 element. Functionally equivalent to collection.size > 1. - def many? + # Works with a block too ala any?, so people.many? { |p| p.age > 26 } # => returns true if more than 1 person is over 26. + def many?(&block) + size = block_given? ? select(&block).size : self.size size > 1 end end -- cgit v1.2.3 From 8d24a029df47fa9ad36f0e027d3cd447f92af344 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 20 Jun 2008 10:39:44 -0700 Subject: Don't assume RubyProf constants are defined --- activesupport/lib/active_support/testing/performance.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb index 1f8a5eec8f..5f2027eb3b 100644 --- a/activesupport/lib/active_support/testing/performance.rb +++ b/activesupport/lib/active_support/testing/performance.rb @@ -288,7 +288,7 @@ module ActiveSupport end class CpuTime < Time - Mode = RubyProf::CPU_TIME + Mode = RubyProf::CPU_TIME if RubyProf.const_defined?(:CPU_TIME) def initialize(*args) # FIXME: yeah my CPU is 2.33 GHz @@ -302,7 +302,7 @@ module ActiveSupport end class Memory < Base - Mode = RubyProf::MEMORY + Mode = RubyProf::MEMORY if RubyProf.const_defined?(:MEMORY) # ruby-prof wrapper if RubyProf.respond_to?(:measure_memory) @@ -335,7 +335,7 @@ module ActiveSupport end class Objects < Base - Mode = RubyProf::ALLOCATIONS + Mode = RubyProf::ALLOCATIONS if RubyProf.const_defined?(:ALLOCATIONS) if RubyProf.respond_to?(:measure_allocations) def measure @@ -353,7 +353,7 @@ module ActiveSupport end class GcRuns < Base - Mode = RubyProf::GC_RUNS + Mode = RubyProf::GC_RUNS if RubyProf.const_defined?(:GC_RUNS) if RubyProf.respond_to?(:measure_gc_runs) def measure @@ -375,7 +375,7 @@ module ActiveSupport end class GcTime < Base - Mode = RubyProf::GC_TIME + Mode = RubyProf::GC_TIME if RubyProf.const_defined?(:GC_TIME) if RubyProf.respond_to?(:measure_gc_time) def measure -- cgit v1.2.3 From 9a0e4437199a233105348938e490808fc0688626 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 21 Jun 2008 04:19:30 -0700 Subject: Everything responds to #to_param --- activesupport/lib/active_support/cache.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 27beff9815..3e3dc18263 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -29,10 +29,8 @@ module ActiveSupport key.cache_key when key.is_a?(Array) key.collect { |element| expand_cache_key(element) }.to_param - when key.respond_to?(:to_param) + when key key.to_param - else - key end.to_s expanded_cache_key -- cgit v1.2.3 From 4d5ac3f3d2e1667971752c9a4e536de1a5bec364 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 22 Jun 2008 20:52:29 -0700 Subject: Check for mocha gem without requiring the lib. [#403 state:resolved] --- activesupport/lib/active_support/testing/setup_and_teardown.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb index 21d71eb92a..d934246d4d 100644 --- a/activesupport/lib/active_support/testing/setup_and_teardown.rb +++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb @@ -18,9 +18,9 @@ module ActiveSupport alias_method :run, :run_with_callbacks_and_miniunit else begin - require 'mocha' + gem 'mocha' alias_method :run, :run_with_callbacks_and_mocha - rescue LoadError + rescue Gem::LoadError alias_method :run, :run_with_callbacks_and_testunit end end -- cgit v1.2.3 From d7462ea36550bd59cfbcd7961f5870c49bcf8963 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 23 Jun 2008 00:31:49 -0700 Subject: Revert "Check for mocha gem without requiring the lib. [#403 state:resolved]" This reverts commit 4d5ac3f3d2e1667971752c9a4e536de1a5bec364. --- activesupport/lib/active_support/testing/setup_and_teardown.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb index d934246d4d..21d71eb92a 100644 --- a/activesupport/lib/active_support/testing/setup_and_teardown.rb +++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb @@ -18,9 +18,9 @@ module ActiveSupport alias_method :run, :run_with_callbacks_and_miniunit else begin - gem 'mocha' + require 'mocha' alias_method :run, :run_with_callbacks_and_mocha - rescue Gem::LoadError + rescue LoadError alias_method :run, :run_with_callbacks_and_testunit end end -- cgit v1.2.3 From 6874caa4070f10cdbe104c9ac97dafd33dbdd282 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 24 Jun 2008 21:49:49 -0700 Subject: Performance: minor Array#to_param and #to_query speedups --- activesupport/lib/active_support/core_ext/array/conversions.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/array/conversions.rb b/activesupport/lib/active_support/core_ext/array/conversions.rb index a9882828ca..49ada8f174 100644 --- a/activesupport/lib/active_support/core_ext/array/conversions.rb +++ b/activesupport/lib/active_support/core_ext/array/conversions.rb @@ -27,7 +27,7 @@ module ActiveSupport #:nodoc: # Calls to_param on all its elements and joins the result with # slashes. This is used by url_for in Action Pack. def to_param - map(&:to_param).join '/' + collect { |e| e.to_param }.join '/' end # Converts an array into a string suitable for use as a URL query string, @@ -35,7 +35,8 @@ module ActiveSupport #:nodoc: # # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding" def to_query(key) - collect { |value| value.to_query("#{key}[]") } * '&' + prefix = "#{key}[]" + collect { |value| value.to_query(prefix) }.join '&' end def self.included(base) #:nodoc: -- cgit v1.2.3 From 071fe79279e89e650acce6613f13027527d01650 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Tue, 24 Jun 2008 22:07:09 -0700 Subject: Include cache key in ModelName --- activesupport/lib/active_support/core_ext/module/model_naming.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/module/model_naming.rb b/activesupport/lib/active_support/core_ext/module/model_naming.rb index 26e76ab556..abb02f1f70 100644 --- a/activesupport/lib/active_support/core_ext/module/model_naming.rb +++ b/activesupport/lib/active_support/core_ext/module/model_naming.rb @@ -1,12 +1,13 @@ module ActiveSupport class ModelName < String - attr_reader :singular, :plural, :partial_path + attr_reader :singular, :plural, :cache_key, :partial_path def initialize(name) super @singular = underscore.tr('/', '_').freeze @plural = @singular.pluralize.freeze - @partial_path = "#{tableize}/#{demodulize.underscore}".freeze + @cache_key = tableize + @partial_path = "#{@cache_key}/#{demodulize.underscore}".freeze end end -- cgit v1.2.3 From 24c7f41b4fdc411e35131f9065852a685032211f Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 25 Jun 2008 15:11:41 -0700 Subject: Freeze ModelName cache_key also --- activesupport/lib/active_support/core_ext/module/model_naming.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/module/model_naming.rb b/activesupport/lib/active_support/core_ext/module/model_naming.rb index abb02f1f70..5518f5417b 100644 --- a/activesupport/lib/active_support/core_ext/module/model_naming.rb +++ b/activesupport/lib/active_support/core_ext/module/model_naming.rb @@ -6,7 +6,7 @@ module ActiveSupport super @singular = underscore.tr('/', '_').freeze @plural = @singular.pluralize.freeze - @cache_key = tableize + @cache_key = tableize.freeze @partial_path = "#{@cache_key}/#{demodulize.underscore}".freeze end end -- cgit v1.2.3 From 582bff71c465075d01b6e062d64b13ac3df4ad56 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 27 Jun 2008 17:19:24 -0700 Subject: Fix typo in apparently-dead will_unload? method. --- activesupport/lib/active_support/dependencies.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 7a8c4d0326..d3d9ff9de4 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -299,7 +299,7 @@ module ActiveSupport #:nodoc: # Will the provided constant descriptor be unloaded? def will_unload?(const_desc) - autoloaded?(desc) || + autoloaded?(const_desc) || explicitly_unloadable_constants.include?(to_constant_name(const_desc)) end -- cgit v1.2.3 From aec3c7aa72c89e37edae4d14ac98d7a6de4a195c Mon Sep 17 00:00:00 2001 From: rick Date: Fri, 27 Jun 2008 23:29:25 -0700 Subject: add special requires for ActiveSupport::Inflector so you can load it individually --- activesupport/lib/active_support/inflector.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb index 47bd6e1767..8d55ad27ac 100644 --- a/activesupport/lib/active_support/inflector.rb +++ b/activesupport/lib/active_support/inflector.rb @@ -307,4 +307,9 @@ module ActiveSupport end end +# in case active_support/inflector is required without the rest of active_support require 'active_support/inflections' +require 'active_support/core_ext/string/inflections' +unless String.included_modules.include?(ActiveSupport::CoreExtensions::String::Inflections) + String.send :include, ActiveSupport::CoreExtensions::String::Inflections +end \ No newline at end of file -- cgit v1.2.3 From d0092dc44d580f4179308c7394d9023098406f79 Mon Sep 17 00:00:00 2001 From: Ernie Miller Date: Sat, 28 Jun 2008 22:27:32 -0400 Subject: Added support for regexp matching of priority zones in time_zone_select [#195 state:resolved] --- activesupport/lib/active_support/values/time_zone.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index 5b2d42aa3c..788d40bfa8 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -201,6 +201,12 @@ module ActiveSupport result end + # Compare #name and TZInfo identifier to a supplied regexp, returning true + # if a match is found. + def =~(re) + return true if name =~ re || MAPPING[name] =~ re + end + # Returns a textual representation of this time zone. def to_s "(GMT#{formatted_offset}) #{name}" -- cgit v1.2.3 From 676d6a651497b56f31e00db4e7795669de0da672 Mon Sep 17 00:00:00 2001 From: gbuesing Date: Sun, 29 Jun 2008 15:17:51 -0500 Subject: TimeWithZone: when crossing DST boundary, treat Durations of days, months or years as variable-length, and all other values as absolute length. A time + 24.hours will advance exactly 24 hours, but a time + 1.day will advance 23-25 hours, depending on the day. Ensure consistent behavior across all advancing methods. --- activesupport/lib/active_support/time_with_zone.rb | 45 ++++++++++++++++------ 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index bfc5b16039..7370a45931 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -159,19 +159,24 @@ module ActiveSupport utc == other end - # If wrapped +time+ is a DateTime, use DateTime#since instead of +. - # Otherwise, just pass on to +method_missing+. def +(other) - result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other) - result.in_time_zone(time_zone) + # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time, + # otherwise move forward from #utc, for accuracy when moving across DST boundaries + if duration_of_variable_length?(other) + method_missing(:+, other) + else + result = utc.acts_like?(:date) ? utc.since(other) : utc + other rescue utc.since(other) + result.in_time_zone(time_zone) + end end - - # If a time-like object is passed in, compare it with +utc+. - # Else if wrapped +time+ is a DateTime, use DateTime#ago instead of DateTime#-. - # Otherwise, just pass on to +method_missing+. + def -(other) + # If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time, + # otherwise move backwards #utc, for accuracy when moving across DST boundaries if other.acts_like?(:time) utc - other + elsif duration_of_variable_length?(other) + method_missing(:-, other) else result = utc.acts_like?(:date) ? utc.ago(other) : utc - other rescue utc.ago(other) result.in_time_zone(time_zone) @@ -179,15 +184,27 @@ module ActiveSupport end def since(other) - utc.since(other).in_time_zone(time_zone) + # If we're adding a Duration of variable length (i.e., years, months, days), move forward from #time, + # otherwise move forward from #utc, for accuracy when moving across DST boundaries + if duration_of_variable_length?(other) + method_missing(:since, other) + else + utc.since(other).in_time_zone(time_zone) + end end def ago(other) - utc.ago(other).in_time_zone(time_zone) + since(-other) end - + def advance(options) - utc.advance(options).in_time_zone(time_zone) + # If we're advancing a value of variable length (i.e., years, months, days), advance from #time, + # otherwise advance from #utc, for accuracy when moving across DST boundaries + if options.detect {|k,v| [:years, :months, :days].include? k} + method_missing(:advance, options) + else + utc.advance(options).in_time_zone(time_zone) + end end %w(year mon month day mday hour min sec).each do |method_name| @@ -279,5 +296,9 @@ module ActiveSupport def transfer_time_values_to_utc_constructor(time) ::Time.utc_time(time.year, time.month, time.day, time.hour, time.min, time.sec, time.respond_to?(:usec) ? time.usec : 0) end + + def duration_of_variable_length?(obj) + ActiveSupport::Duration === obj && obj.parts.flatten.detect {|p| [:years, :months, :days].include? p } + end end end -- cgit v1.2.3 From 6f1d827096ad9f1044a6da7141e7ae720a64ec6b Mon Sep 17 00:00:00 2001 From: gbuesing Date: Sun, 29 Jun 2008 15:26:56 -0500 Subject: TimeWithZone#advance: treat :weeks option as variable-length --- activesupport/lib/active_support/time_with_zone.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index 7370a45931..88593eb92d 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -198,9 +198,9 @@ module ActiveSupport end def advance(options) - # If we're advancing a value of variable length (i.e., years, months, days), advance from #time, + # If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time, # otherwise advance from #utc, for accuracy when moving across DST boundaries - if options.detect {|k,v| [:years, :months, :days].include? k} + if options.detect {|k,v| [:years, :weeks, :months, :days].include? k} method_missing(:advance, options) else utc.advance(options).in_time_zone(time_zone) -- cgit v1.2.3 From 4f75840d72b96fff34d65b59480da7d6c7494120 Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Wed, 2 Jul 2008 13:25:17 +0100 Subject: Add Inflection rules for String#humanize. [#535 state:resolved] [dcmanges] Signed-off-by: Pratik Naik --- activesupport/lib/active_support/inflector.rb | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb index 8d55ad27ac..6651569d33 100644 --- a/activesupport/lib/active_support/inflector.rb +++ b/activesupport/lib/active_support/inflector.rb @@ -30,10 +30,10 @@ module ActiveSupport class Inflections include Singleton - attr_reader :plurals, :singulars, :uncountables + attr_reader :plurals, :singulars, :uncountables, :humans def initialize - @plurals, @singulars, @uncountables = [], [], [] + @plurals, @singulars, @uncountables, @humans = [], [], [], [] end # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression. @@ -76,9 +76,20 @@ module ActiveSupport (@uncountables << words).flatten! end + # Specifies a humanized form of a string by a regular expression rule or by a string mapping. + # When using a regular expression based replacement, the normal humanize formatting is called after the replacement. + # When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name') + # + # Examples: + # human /_cnt$/i, '\1_count' + # human "legacy_col_person_name", "Name" + def human(rule, replacement) + @humans.insert(0, [rule, replacement]) + end + # Clears the loaded inflections within a given scope (default is :all). # Give the scope as a symbol of the inflection type, the options are: :plurals, - # :singulars, :uncountables. + # :singulars, :uncountables, :humans. # # Examples: # clear :all @@ -209,7 +220,10 @@ module ActiveSupport # "employee_salary" # => "Employee salary" # "author_id" # => "Author" def humanize(lower_case_and_underscored_word) - lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize + result = lower_case_and_underscored_word.to_s.dup + + inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) } + result.gsub(/_id$/, "").gsub(/_/, " ").capitalize end # Removes the module part from the expression in the string. -- cgit v1.2.3 From 51e13d51adee3c69feab30aa4c0b08d2278ccc5f Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Sun, 22 Jun 2008 13:44:21 +0300 Subject: Move test related core_ext stuff out of regular core ext to prevent nasty surprises when you require active_support then use Test::Unit directly. --- activesupport/lib/active_support/core_ext/test.rb | 1 - .../core_ext/test/unit/assertions.rb | 64 --------------------- activesupport/lib/active_support/test_case.rb | 6 +- .../lib/active_support/testing/core_ext/test.rb | 6 ++ .../testing/core_ext/test/unit/assertions.rb | 65 ++++++++++++++++++++++ 5 files changed, 72 insertions(+), 70 deletions(-) delete mode 100644 activesupport/lib/active_support/core_ext/test.rb delete mode 100644 activesupport/lib/active_support/core_ext/test/unit/assertions.rb create mode 100644 activesupport/lib/active_support/testing/core_ext/test.rb create mode 100644 activesupport/lib/active_support/testing/core_ext/test/unit/assertions.rb (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/test.rb b/activesupport/lib/active_support/core_ext/test.rb deleted file mode 100644 index c0b19bdc58..0000000000 --- a/activesupport/lib/active_support/core_ext/test.rb +++ /dev/null @@ -1 +0,0 @@ -require 'active_support/core_ext/test/unit/assertions' diff --git a/activesupport/lib/active_support/core_ext/test/unit/assertions.rb b/activesupport/lib/active_support/core_ext/test/unit/assertions.rb deleted file mode 100644 index 77fe325fb4..0000000000 --- a/activesupport/lib/active_support/core_ext/test/unit/assertions.rb +++ /dev/null @@ -1,64 +0,0 @@ -module Test - module Unit - #-- - # FIXME: no Proc#binding in Ruby 2, must change this API - #++ - module Assertions - # Test numeric difference between the return value of an expression as a result of what is evaluated - # in the yielded block. - # - # assert_difference 'Article.count' do - # post :create, :article => {...} - # end - # - # An arbitrary expression is passed in and evaluated. - # - # assert_difference 'assigns(:article).comments(:reload).size' do - # post :create, :comment => {...} - # end - # - # An arbitrary positive or negative difference can be specified. The default is +1. - # - # assert_difference 'Article.count', -1 do - # post :delete, :id => ... - # end - # - # An array of expressions can also be passed in and evaluated. - # - # assert_difference [ 'Article.count', 'Post.count' ], +2 do - # post :create, :article => {...} - # end - # - # A error message can be specified. - # - # assert_difference 'Article.count', -1, "An Article should be destroyed" do - # post :delete, :id => ... - # end - def assert_difference(expressions, difference = 1, message = nil, &block) - expression_evaluations = Array(expressions).collect{ |expression| lambda { eval(expression, block.send!(:binding)) } } - - original_values = expression_evaluations.inject([]) { |memo, expression| memo << expression.call } - yield - expression_evaluations.each_with_index do |expression, i| - assert_equal original_values[i] + difference, expression.call, message - end - end - - # Assertion that the numeric result of evaluating an expression is not changed before and after - # invoking the passed in block. - # - # assert_no_difference 'Article.count' do - # post :create, :article => invalid_attributes - # end - # - # A error message can be specified. - # - # assert_no_difference 'Article.count', "An Article should not be destroyed" do - # post :create, :article => invalid_attributes - # end - def assert_no_difference(expressions, message = nil, &block) - assert_difference expressions, 0, message, &block - end - end - end -end diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb index 2fd02d5313..0f531b0c79 100644 --- a/activesupport/lib/active_support/test_case.rb +++ b/activesupport/lib/active_support/test_case.rb @@ -1,11 +1,7 @@ require 'test/unit/testcase' -require 'active_support/testing/setup_and_teardown' require 'active_support/testing/default' +require 'active_support/testing/core_ext/test' -# TODO: move to core_ext -class Test::Unit::TestCase #:nodoc: - include ActiveSupport::Testing::SetupAndTeardown -end module ActiveSupport class TestCase < Test::Unit::TestCase diff --git a/activesupport/lib/active_support/testing/core_ext/test.rb b/activesupport/lib/active_support/testing/core_ext/test.rb new file mode 100644 index 0000000000..d3f38f0bc7 --- /dev/null +++ b/activesupport/lib/active_support/testing/core_ext/test.rb @@ -0,0 +1,6 @@ +require 'active_support/testing/core_ext/test/unit/assertions' +require 'active_support/testing/setup_and_teardown' + +class Test::Unit::TestCase #:nodoc: + include ActiveSupport::Testing::SetupAndTeardown +end \ No newline at end of file diff --git a/activesupport/lib/active_support/testing/core_ext/test/unit/assertions.rb b/activesupport/lib/active_support/testing/core_ext/test/unit/assertions.rb new file mode 100644 index 0000000000..70a44eab8c --- /dev/null +++ b/activesupport/lib/active_support/testing/core_ext/test/unit/assertions.rb @@ -0,0 +1,65 @@ +require 'test/unit/assertions' +module Test + module Unit + #-- + # FIXME: no Proc#binding in Ruby 2, must change this API + #++ + module Assertions + # Test numeric difference between the return value of an expression as a result of what is evaluated + # in the yielded block. + # + # assert_difference 'Article.count' do + # post :create, :article => {...} + # end + # + # An arbitrary expression is passed in and evaluated. + # + # assert_difference 'assigns(:article).comments(:reload).size' do + # post :create, :comment => {...} + # end + # + # An arbitrary positive or negative difference can be specified. The default is +1. + # + # assert_difference 'Article.count', -1 do + # post :delete, :id => ... + # end + # + # An array of expressions can also be passed in and evaluated. + # + # assert_difference [ 'Article.count', 'Post.count' ], +2 do + # post :create, :article => {...} + # end + # + # A error message can be specified. + # + # assert_difference 'Article.count', -1, "An Article should be destroyed" do + # post :delete, :id => ... + # end + def assert_difference(expressions, difference = 1, message = nil, &block) + expression_evaluations = Array(expressions).collect{ |expression| lambda { eval(expression, block.send!(:binding)) } } + + original_values = expression_evaluations.inject([]) { |memo, expression| memo << expression.call } + yield + expression_evaluations.each_with_index do |expression, i| + assert_equal original_values[i] + difference, expression.call, message + end + end + + # Assertion that the numeric result of evaluating an expression is not changed before and after + # invoking the passed in block. + # + # assert_no_difference 'Article.count' do + # post :create, :article => invalid_attributes + # end + # + # A error message can be specified. + # + # assert_no_difference 'Article.count', "An Article should not be destroyed" do + # post :create, :article => invalid_attributes + # end + def assert_no_difference(expressions, message = nil, &block) + assert_difference expressions, 0, message, &block + end + end + end +end -- cgit v1.2.3 From ce4a1bb8538bd7cc5ee3cbf1156dc587482a7839 Mon Sep 17 00:00:00 2001 From: Cheah Chu Yeow Date: Thu, 26 Jun 2008 10:21:53 +0800 Subject: Remove some Symbol#to_proc usage in runtime code. [#484 state:resolved] --- activesupport/lib/active_support/core_ext/module/introspection.rb | 2 +- .../lib/active_support/core_ext/object/instance_variables.rb | 2 +- activesupport/lib/active_support/dependencies.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/module/introspection.rb b/activesupport/lib/active_support/core_ext/module/introspection.rb index 40bbebb7c4..bb894ec080 100644 --- a/activesupport/lib/active_support/core_ext/module/introspection.rb +++ b/activesupport/lib/active_support/core_ext/module/introspection.rb @@ -70,6 +70,6 @@ class Module # Returns the names of the constants defined locally rather than the # constants themselves. See local_constants. def local_constant_names - local_constants.map(&:to_s) + local_constants.map { |c| c.to_s } end end diff --git a/activesupport/lib/active_support/core_ext/object/instance_variables.rb b/activesupport/lib/active_support/core_ext/object/instance_variables.rb index 9f1d4ed2aa..4ecaab3bbb 100644 --- a/activesupport/lib/active_support/core_ext/object/instance_variables.rb +++ b/activesupport/lib/active_support/core_ext/object/instance_variables.rb @@ -35,7 +35,7 @@ class Object # C.new(0, 1).instance_variable_names # => ["@y", "@x"] if RUBY_VERSION >= '1.9' def instance_variable_names - instance_variables.map(&:to_s) + instance_variables.map { |var| var.to_s } end else alias_method :instance_variable_names, :instance_variables diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index d3d9ff9de4..2f3fa72bb4 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -387,7 +387,7 @@ module ActiveSupport #:nodoc: ensure # Remove the stack frames that we added. if defined?(watch_frames) && ! watch_frames.blank? - frame_ids = watch_frames.collect(&:object_id) + frame_ids = watch_frames.collect { |frame| frame.object_id } constant_watch_stack.delete_if do |watch_frame| frame_ids.include? watch_frame.object_id end @@ -437,7 +437,7 @@ module ActiveSupport #:nodoc: protected def log_call(*args) if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity - arg_str = args.collect(&:inspect) * ', ' + arg_str = args.collect { |arg| arg.inspect } * ', ' /in `([a-z_\?\!]+)'/ =~ caller(1).first selector = $1 || '' log "called #{selector}(#{arg_str})" -- cgit v1.2.3 From 9783e66cade4d145389cca18fab822f44d03161a Mon Sep 17 00:00:00 2001 From: Pratik Naik Date: Mon, 14 Jul 2008 01:02:07 +0100 Subject: Slightly faster DateTime#to_json. [#598 state:resolved] [Alex Zepeda] --- activesupport/lib/active_support/json/encoders/date_time.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/json/encoders/date_time.rb b/activesupport/lib/active_support/json/encoders/date_time.rb index d41c3e9786..a4a5efbfb1 100644 --- a/activesupport/lib/active_support/json/encoders/date_time.rb +++ b/activesupport/lib/active_support/json/encoders/date_time.rb @@ -8,7 +8,7 @@ class DateTime if ActiveSupport.use_standard_json_time_format xmlschema.inspect else - %("#{strftime("%Y/%m/%d %H:%M:%S %z")}") + strftime('"%Y/%m/%d %H:%M:%S %z"') end end end -- cgit v1.2.3 From 269c6c6bcfec342cf830e0b20c44bb2c888e8fdf Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Wed, 9 Jul 2008 19:43:38 -0700 Subject: Cache Module#parent_name --- .../core_ext/module/introspection.rb | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/module/introspection.rb b/activesupport/lib/active_support/core_ext/module/introspection.rb index bb894ec080..45f3e4bf5c 100644 --- a/activesupport/lib/active_support/core_ext/module/introspection.rb +++ b/activesupport/lib/active_support/core_ext/module/introspection.rb @@ -1,4 +1,14 @@ class Module + # Returns the name of the module containing this one. + # + # p M::N.parent_name # => "M" + def parent_name + unless defined? @parent_name + @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil + end + @parent_name + end + # Returns the module which contains this one according to its name. # # module M @@ -16,8 +26,7 @@ class Module # p Module.new.parent # => Object # def parent - parent_name = name.split('::')[0..-2] * '::' - parent_name.empty? ? Object : parent_name.constantize + parent_name ? parent_name.constantize : Object end # Returns all the parents of this module according to its name, ordered from @@ -35,10 +44,12 @@ class Module # def parents parents = [] - parts = name.split('::')[0..-2] - until parts.empty? - parents << (parts * '::').constantize - parts.pop + if parent_name + parts = parent_name.split('::') + until parts.empty? + parents << (parts * '::').constantize + parts.pop + end end parents << Object unless parents.include? Object parents -- cgit v1.2.3 From 8a9934a9d9fc98b56c4566ae2e3fd4d83e505d3e Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 14 Jul 2008 19:50:32 -0500 Subject: Added Memoizable mixin for caching simple lazy loaded attributes --- activesupport/lib/active_support/memoizable.rb | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 activesupport/lib/active_support/memoizable.rb (limited to 'activesupport/lib/active_support') 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 -- cgit v1.2.3 From 001c8beb4d0999a858a8b52ad511ee1251cc3517 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 14 Jul 2008 20:02:59 -0500 Subject: memorize typo --- activesupport/lib/active_support/memoizable.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb index c78fb0a793..65feca363a 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -5,8 +5,8 @@ module ActiveSupport end module ClassMethods - def memorize(symbol) - original_method = "_unmemorized_#{symbol}" + def memoize(symbol) + original_method = "_unmemoized_#{symbol}" alias_method original_method, symbol class_eval <<-EOS, __FILE__, __LINE__ def #{symbol} @@ -22,7 +22,7 @@ module ActiveSupport def freeze methods.each do |method| - if m = method.to_s.match(/^_unmemorized_(.*)/) + if m = method.to_s.match(/^_unmemoized_(.*)/) send(m[1]).freeze end end -- cgit v1.2.3 From 911c2c381347ffb04615896ee6afe45277eeb103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20T=C3=A4nav?= Date: Mon, 14 Jul 2008 20:23:23 -0500 Subject: Some performance tweaks to ActiveSupport::Memoizable Signed-off-by: Joshua Peek --- activesupport/lib/active_support/memoizable.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb index 65feca363a..5af50df023 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -7,10 +7,12 @@ module ActiveSupport module ClassMethods def memoize(symbol) original_method = "_unmemoized_#{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} - if instance_variable_defined?(:@#{symbol}) + if defined? @#{symbol} @#{symbol} else @#{symbol} = #{original_method} @@ -22,7 +24,7 @@ module ActiveSupport def freeze methods.each do |method| - if m = method.to_s.match(/^_unmemoized_(.*)/) + if m = method.to_s.match(/\A_unmemoized_(.*)/) send(m[1]).freeze end end -- cgit v1.2.3 From 7f0346237e30e55d6cd16a8b4a9dfe4193f61804 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 14 Jul 2008 20:25:09 -0500 Subject: Append a "_" to memoized instance variables --- activesupport/lib/active_support/memoizable.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb index 5af50df023..d06250171a 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -7,15 +7,16 @@ module ActiveSupport module ClassMethods def memoize(symbol) original_method = "_unmemoized_#{symbol}" + memoized_ivar = "@_memoized_#{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} - if defined? @#{symbol} - @#{symbol} + if defined? #{memoized_ivar} + #{memoized_ivar} else - @#{symbol} = #{original_method} + #{memoized_ivar} = #{original_method} end end EOS -- cgit v1.2.3 From 34510456585216004e483b79beeea3ddc3eb4de6 Mon Sep 17 00:00:00 2001 From: gbuesing Date: Mon, 14 Jul 2008 23:16:39 -0500 Subject: Fix TimeWithZone unmarshaling: coerce unmarshaled Time instances to utc, because Ruby's marshaling of Time instances doesn't respect the zone --- activesupport/lib/active_support/time_with_zone.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index 88593eb92d..e85bfe9b2e 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -263,7 +263,7 @@ module ActiveSupport end def marshal_load(variables) - initialize(variables[0], ::Time.send!(:get_zone, variables[1]), variables[2]) + initialize(variables[0].utc, ::Time.send!(:get_zone, variables[1]), variables[2].utc) end # Ensure proxy class responds to all methods that underlying time instance responds to. -- cgit v1.2.3 From fc89a951933638b051bb1f9e1339ee6ae7c94cda Mon Sep 17 00:00:00 2001 From: Adrian Mugnolo Date: Tue, 15 Jul 2008 01:17:03 -0300 Subject: Add in_groups to ActiveSupport::CoreExtensions::Array::Grouping. [#579 state:resolved] Signed-off-by: Pratik Naik --- .../lib/active_support/core_ext/array/grouping.rb | 47 +++++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'activesupport/lib/active_support') diff --git a/activesupport/lib/active_support/core_ext/array/grouping.rb b/activesupport/lib/active_support/core_ext/array/grouping.rb index 767acc4e07..df37afb053 100644 --- a/activesupport/lib/active_support/core_ext/array/grouping.rb +++ b/activesupport/lib/active_support/core_ext/array/grouping.rb @@ -4,8 +4,8 @@ module ActiveSupport #:nodoc: module CoreExtensions #:nodoc: module Array #:nodoc: module Grouping - # Iterates over the array in groups of size +number+, padding any remaining - # slots with +fill_with+ unless it is +false+. + # Splits or iterates over the array in groups of size +number+, + # padding any remaining slots with +fill_with+ unless it is +false+. # # %w(1 2 3 4 5 6 7).in_groups_of(3) {|g| p g} # ["1", "2", "3"] @@ -39,6 +39,49 @@ module ActiveSupport #:nodoc: end end + # Splits or iterates over the array in +number+ of groups, padding any + # remaining slots with +fill_with+ unless it is +false+. + # + # %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|g| p g} + # ["1", "2", "3", "4"] + # ["5", "6", "7", nil] + # ["8", "9", "10", nil] + # + # %w(1 2 3 4 5 6 7).in_groups(3, ' ') {|g| p g} + # ["1", "2", "3"] + # ["4", "5", " "] + # ["6", "7", " "] + # + # %w(1 2 3 4 5 6 7).in_groups(3, false) {|g| p g} + # ["1", "2", "3"] + # ["4", "5"] + # ["6", "7"] + def in_groups(number, fill_with = nil) + # size / number gives minor group size; + # size % number gives how many objects need extra accomodation; + # each group hold either division or division + 1 items. + division = size / number + modulo = size % number + + # create a new array avoiding dup + groups = [] + start = 0 + + number.times do |index| + length = division + (modulo > 0 && modulo > index ? 1 : 0) + padding = fill_with != false && + modulo > 0 && length == division ? 1 : 0 + groups << slice(start, length).concat([fill_with] * padding) + start += length + end + + if block_given? + groups.each{|g| yield(g) } + else + groups + end + end + # Divides the array into one or more subarrays based on a delimiting +value+ # or the result of an optional block. # -- cgit v1.2.3