aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activesupport/lib/active_support/core_ext/enumerable.rb9
-rw-r--r--activesupport/test/core_ext/enumerable_test.rb2
2 files changed, 11 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/core_ext/enumerable.rb b/activesupport/lib/active_support/core_ext/enumerable.rb
index e89b7e392e..d68eef8c23 100644
--- a/activesupport/lib/active_support/core_ext/enumerable.rb
+++ b/activesupport/lib/active_support/core_ext/enumerable.rb
@@ -111,3 +111,12 @@ module Enumerable
!any?(&block)
end unless [].respond_to?(:none?)
end
+
+class Range #:nodoc:
+ # Optimize range sum to use arithmetic progression if a block is not given.
+ def sum(identity=0, &block)
+ return super if block_given?
+ actual_last = exclude_end? ? (last - 1) : last
+ (actual_last - first + 1) * (actual_last + first) / 2
+ end
+end
diff --git a/activesupport/test/core_ext/enumerable_test.rb b/activesupport/test/core_ext/enumerable_test.rb
index 1927a0ad0d..6512754e53 100644
--- a/activesupport/test/core_ext/enumerable_test.rb
+++ b/activesupport/test/core_ext/enumerable_test.rb
@@ -61,7 +61,9 @@ class EnumerableTests < Test::Unit::TestCase
end
def test_enumerable_sums
+ assert_equal 20, (1..4).sum { |i| i * 2 }
assert_equal 10, (1..4).sum
+ assert_equal 6, (1...4).sum
end
def test_each_with_object