Project

General

Profile

Bug #13700

Enumerable#sum may not work for Ranges subclasses due to optimization

Added by sos4nt (Stefan Schüßler) over 1 year ago. Updated over 1 year ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin15]
[ruby-core:81847]

Description

Enumerable#sum is optimized for integer ranges. Unfortunately, this can break subclasses:

class StepTwoRange < Range
  def each(&block)
    step(2, &block)
  end
end

r = StepTwoRange.new(0, 10)
r.to_a     #=> [0, 2, 4, 6, 8, 10]

r.to_a.sum #=> 30
r.sum      #=> 55

The optimization should therefore only be triggered for instances of Range and not for instances of subclasses. (or more specifically, not for subclasses overriding each)

If this behavior is intentional, it should at least be documented.

History

#1

Updated by sos4nt (Stefan Schüßler) over 1 year ago

  • Description updated (diff)
#2

Updated by sos4nt (Stefan Schüßler) over 1 year ago

  • Description updated (diff)

Updated by shevegen (Robert A. Heiler) over 1 year ago

Reminds me a bit of what hanmac wrote elsewhere; I can't find it right now and forgot it mostly already but I think he also mentioned some unexpected behaviour when ... subclassing I think? Or some custom class that he wrote...

Updated by Hanmac (Hans Mackowiak) over 1 year ago

shevegen (Robert A. Heiler) wrote:

Reminds me a bit of what hanmac wrote elsewhere; I can't find it right now and forgot it mostly already but I think he also mentioned some unexpected behaviour when ... subclassing I think? Or some custom class that he wrote...

my comment was for https://bugs.ruby-lang.org/issues/13663
with String#upto you can't overwrite the internal String#<=>

Updated by sos4nt (Stefan Schüßler) over 1 year ago

Side note: in my opinion, Enumerable should not check the receiver's class to provide specific optimizations. Instead, Range should override sum and handle the optimization itself. Range#sum would also be a better place to document this behavior. (it still doesn't solve the subclassing issue, though)

Also available in: Atom PDF