From: "nagachika (Tomoyuki Chikanaga) via ruby-core" Date: 2024-05-16T04:10:57+00:00 Subject: [ruby-core:117891] [Ruby master Bug#19530] `Array#sum` and `Enumerable#sum` sometimes show different behaviours 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)) #=> # 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/array.c#L8133-L8137) 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/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/