Project

General

Profile

Bug #14048

Enumerable#sum sometimes assumes objects are `Range`s when they're not

Added by rohitpaulk (Paul Kuruvilla) about 3 years ago. Updated about 3 years ago.

Status:
Closed
Priority:
Normal
Target version:
-
ruby -v:
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin16]
[ruby-core:83541]

Description

If a class defines the methods begin and end, Enumerable assumes that it is a Range object and tries to access the exclude_end? method.

class NotARange
  include Enumerable # Defines the `#sum` method

  def each
    yield 2
    yield 4
    yield 6
  end

  def begin; end
  def end; end
end

not_a_range = NotARange.new
puts not_a_range.sum

The above program throws an error:

main.rb:20:in `sum': undefined method `exclude_end?' for #<NotARange:0x00007f8750950c70> (NoMethodError)

If either begin or end are not defined though, it works fine and returns 12.

It looks like the commit that introduced this was: https://github.com/ruby/ruby/commit/53b4c2b87a9c6832e663cf5773a8aca9a1cf3341

I think that Enumerable should only attempt to perform the optimization on objects that are indeed Range or subclasses of Range.

Updated by mrkn (Kenta Murata) about 3 years ago

  • Assignee set to mrkn (Kenta Murata)
#2

Updated by nobu (Nobuyoshi Nakada) about 3 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r60411.


range.c: check if exclude_end? is defined

  • range.c (rb_range_values): should raise TypeError if necessary method is not defined, not NoMethodError, when trying to tell if the object is a Range and extract info. [ruby-core:83541] [Bug #14048]

Also available in: Atom PDF