Bug #19426
closed
Endless `Range#step` of object with `#succ` method does not work
Added by nobu (Nobuyoshi Nakada) almost 2 years ago.
Updated almost 2 years ago.
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>'
- 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
- 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.
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.
- Status changed from Closed to Open
I agree with moving nil comparison.
Matz.
- Status changed from Open to Closed
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0