
Issue #19530 has been updated by nagachika (Tomoyuki Chikanaga). Backport changed from 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED to 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: WONTFIX Since this was a long standing bug, I won't backport it to stable branch in general. If you know any real applications suffered from this behavior, please let me know. Thanks. ---------------------------------------- Bug #19530: `Array#sum` and `Enumerable#sum` sometimes show different behaviours https://bugs.ruby-lang.org/issues/19530#change-108307 * Author: dstosik (David Stosik) * Status: Closed * ruby -v: ruby 3.2.1 (2023-02-08 revision 31819e82c8) [arm64-darwin22] * Backport: 2.7: WONTFIX, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: WONTFIX ---------------------------------------- Hi everyone. 👋🏻 We recently discovered that `Array#sum` and `Enumerable#sum` will output different results in some edge cases. Here's the smallest script I managed to write to reproduce the issue: ``` ruby class Money def initialize(amount) @amount = amount.to_f end def +(other) self.class.new(@amount + other.to_f) end def to_f @amount end end p [7.0].each.sum(Money.new(0)) #=> #<Money:0x00000001005b35f0 @amount=7.0> p [7.0] .sum(Money.new(0)) #=> 7.0 💥 ``` I understand that it is expected that `#sum` may not honor custom definitions of the `#+` method (particularly when the summed values are `Float`). However, I would like to bring your attention to the fact that, in the example above, calling `#sum` on an `Array` of `Float` values and calling `#sum` on an `Enumerable` that yields the same `Float` values will return results of different types. I've reproduced the same behaviour with multiple versions of Ruby going from 2.6.5 to 3.2.1. Ideally, I would expect `[7.0].sum(Money.new(0))` to return a `Money` object identical to the one returned by `[7.0].each.sum(Money.new(0))`. I think it would make sense if at least they returned an identical value (even if it is a `Float`). Addendum: I forgot to mention [this extract](https://github.com/ruby/ruby/blob/da9c84f859db292ab1127f7ca9b7741fff06557b/a...) of the `Array#sum` documentation:
When no block is given, returns the object equivalent to:
``` ruby sum = init array.each {|element| sum += element } sum ```
With the example above, it would indeed return a `Money` object. -- https://bugs.ruby-lang.org/