Project

General

Profile

Actions

Bug #19426

closed

Endless `Range#step` of object with `#succ` method does not work

Added by nobu (Nobuyoshi Nakada) about 1 year ago. Updated about 1 year ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:112301]

Description

Consider this c object which hash #succ method.

c = Struct.new(:i) do
  def succ; self.class.new(i+1); end
  def <=>(other) i <=> other.i;end
end.new(0)

This Range#step works.

(c..c.succ).step(1) do |d|
  p d.i # 0, 1
end

But it fails on an endless range.

(c..).step(1) do |d|
  p d.i
  break if d.i > 3
end
-:3:in `<=>': undefined method `i' for nil:NilClass (NoMethodError)
	from -:10:in `step'
	from -:10:in `<main>'
Actions #1

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

  • Backport changed from 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN to 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED

Updated by matz (Yukihiro Matsumoto) about 1 year ago

  • Status changed from Open to Closed

Error was caused because the definition of <=> does not conform to the expectation that it should return nil for incomparable objects.

Matz.

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

Sorry that I merged the PR before seeing the reply.

With the same object, Range#each works as expected.

(c..).each do |d|
  p d.i
  break if d.i > 3
end

This is because c is not compared against nil first.
I think #step should behave like this.

Actions #4

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

  • Status changed from Closed to Open

Updated by matz (Yukihiro Matsumoto) about 1 year ago

I agree with moving nil comparison.

Matz.

Actions #6

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

  • Status changed from Open to Closed
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0