未验证 提交 a678c47f 编写于 作者: K Kenta Murata 提交者: Jeremy Daer

Fix initial value effects for sum along to ruby 2.4

Signed-off-by: NJeremy Daer <jeremydaer@gmail.com>
上级 46e0666b
......@@ -17,11 +17,12 @@ module Enumerable
# The default sum of an empty list is zero. You can override this default:
#
# [].sum(Payment.new(0)) { |i| i.amount } # => Payment.new(0)
def sum(identity = 0, &block)
def sum(identity = nil, &block)
if block_given?
map(&block).sum(identity)
else
inject(:+) || identity
sum = identity ? inject(identity, :+) : inject(:+)
sum || identity || 0
end
end
......@@ -91,15 +92,16 @@ def pluck(*keys)
class Range #:nodoc:
# Optimize range sum to use arithmetic progression if a block is not given and
# we have a range of numeric values.
def sum(identity = 0)
def sum(identity = nil)
if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer))
super
else
actual_last = exclude_end? ? (last - 1) : last
if actual_last >= first
(actual_last - first + 1) * (actual_last + first) / 2
sum = identity || 0
sum + (actual_last - first + 1) * (actual_last + first) / 2
else
identity
identity || 0
end
end
end
......
......@@ -22,6 +22,11 @@ def each
end
end
def assert_typed_equal(e, v, cls, msg=nil)
assert_kind_of(cls, v, msg)
assert_equal(e, v, msg)
end
def test_sums
enum = GenericEnumerable.new([5, 15, 10])
assert_equal 30, enum.sum
......@@ -38,6 +43,40 @@ def test_sums
payments = GenericEnumerable.new([ SummablePayment.new(5), SummablePayment.new(15) ])
assert_equal SummablePayment.new(20), payments.sum
assert_equal SummablePayment.new(20), payments.sum { |p| p }
sum = GenericEnumerable.new([3, 5.quo(1)]).sum
assert_typed_equal(8, sum, Rational)
sum = GenericEnumerable.new([3, 5.quo(1)]).sum(0.0)
assert_typed_equal(8.0, sum, Float)
sum = GenericEnumerable.new([3, 5.quo(1), 7.0]).sum
assert_typed_equal(15.0, sum, Float)
sum = GenericEnumerable.new([3, 5.quo(1), Complex(7)]).sum
assert_typed_equal(Complex(15), sum, Complex)
assert_typed_equal(15, sum.real, Rational)
assert_typed_equal(0, sum.imag, Integer)
sum = GenericEnumerable.new([3.5, 5]).sum
assert_typed_equal(8.5, sum, Float)
sum = GenericEnumerable.new([2, 8.5]).sum
assert_typed_equal(10.5, sum, Float)
sum = GenericEnumerable.new([1.quo(2), 1]).sum
assert_typed_equal(3.quo(2), sum, Rational)
sum = GenericEnumerable.new([1.quo(2), 1.quo(3)]).sum
assert_typed_equal(5.quo(6), sum, Rational)
sum = GenericEnumerable.new([2.0, 3.0*Complex::I]).sum
assert_typed_equal(Complex(2.0, 3.0), sum, Complex)
assert_typed_equal(2.0, sum.real, Float)
assert_typed_equal(3.0, sum.imag, Float)
sum = GenericEnumerable.new([1, 2]).sum(10) {|v| v * 2 }
assert_typed_equal(16, sum, Integer)
end
def test_nil_sums
......@@ -55,6 +94,7 @@ def test_empty_sums
assert_equal 0, GenericEnumerable.new([]).sum
assert_equal 0, GenericEnumerable.new([]).sum { |i| i + 10 }
assert_equal Payment.new(0), GenericEnumerable.new([]).sum(Payment.new(0))
assert_typed_equal 0.0, GenericEnumerable.new([]).sum(0.0), Float
end
def test_range_sums
......@@ -68,6 +108,10 @@ def test_range_sums
assert_equal 5, (10..0).sum(5)
assert_equal 10, (10..10).sum
assert_equal 42, (10...10).sum(42)
assert_typed_equal 20.0, (1..4).sum(0.0) { |i| i * 2 }, Float
assert_typed_equal 10.0, (1..4).sum(0.0), Float
assert_typed_equal 20.0, (1..4).sum(10.0), Float
assert_typed_equal 5.0, (10..0).sum(5.0), Float
end
def test_array_sums
......@@ -86,6 +130,40 @@ def test_array_sums
payments = [ SummablePayment.new(5), SummablePayment.new(15) ]
assert_equal SummablePayment.new(20), payments.sum
assert_equal SummablePayment.new(20), payments.sum { |p| p }
sum = [3, 5.quo(1)].sum
assert_typed_equal(8, sum, Rational)
sum = [3, 5.quo(1)].sum(0.0)
assert_typed_equal(8.0, sum, Float)
sum = [3, 5.quo(1), 7.0].sum
assert_typed_equal(15.0, sum, Float)
sum = [3, 5.quo(1), Complex(7)].sum
assert_typed_equal(Complex(15), sum, Complex)
assert_typed_equal(15, sum.real, Rational)
assert_typed_equal(0, sum.imag, Integer)
sum = [3.5, 5].sum
assert_typed_equal(8.5, sum, Float)
sum = [2, 8.5].sum
assert_typed_equal(10.5, sum, Float)
sum = [1.quo(2), 1].sum
assert_typed_equal(3.quo(2), sum, Rational)
sum = [1.quo(2), 1.quo(3)].sum
assert_typed_equal(5.quo(6), sum, Rational)
sum = [2.0, 3.0*Complex::I].sum
assert_typed_equal(Complex(2.0, 3.0), sum, Complex)
assert_typed_equal(2.0, sum.real, Float)
assert_typed_equal(3.0, sum.imag, Float)
sum = [1, 2].sum(10) {|v| v * 2 }
assert_typed_equal(16, sum, Integer)
end
def test_index_by
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册