[ruby-core:112301] [Ruby master Bug#19426] Endless `Range#step` of object with `#succ` method does not work

Issue #19426 has been reported by nobu (Nobuyoshi Nakada). ---------------------------------------- Bug #19426: Endless `Range#step` of object with `#succ` method does not work https://bugs.ruby-lang.org/issues/19426 * Author: nobu (Nobuyoshi Nakada) * Status: Open * Priority: Normal * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Consider this `c` object which hash `#succ` method. ```ruby 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. ```ruby (c..c.succ).step(1) do |d| p d.i # 0, 1 end ``` But it fails on an endless range. ```ruby (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>' ``` -- https://bugs.ruby-lang.org/

Issue #19426 has been updated by matz (Yukihiro Matsumoto). 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. ---------------------------------------- Bug #19426: Endless `Range#step` of object with `#succ` method does not work https://bugs.ruby-lang.org/issues/19426#change-101738 * Author: nobu (Nobuyoshi Nakada) * Status: Closed * Priority: Normal * Backport: 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- Consider this `c` object which hash `#succ` method. ```ruby 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. ```ruby (c..c.succ).step(1) do |d| p d.i # 0, 1 end ``` But it fails on an endless range. ```ruby (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>' ``` -- https://bugs.ruby-lang.org/

Issue #19426 has been updated by nobu (Nobuyoshi Nakada). Sorry that I merged the PR before seeing the reply. With the same object, `Range#each` works as expected. ```ruby (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. ---------------------------------------- Bug #19426: Endless `Range#step` of object with `#succ` method does not work https://bugs.ruby-lang.org/issues/19426#change-101739 * Author: nobu (Nobuyoshi Nakada) * Status: Closed * Priority: Normal * Backport: 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- Consider this `c` object which hash `#succ` method. ```ruby 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. ```ruby (c..c.succ).step(1) do |d| p d.i # 0, 1 end ``` But it fails on an endless range. ```ruby (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>' ``` -- https://bugs.ruby-lang.org/

Issue #19426 has been updated by matz (Yukihiro Matsumoto). I agree with moving nil comparison. Matz. ---------------------------------------- Bug #19426: Endless `Range#step` of object with `#succ` method does not work https://bugs.ruby-lang.org/issues/19426#change-101771 * Author: nobu (Nobuyoshi Nakada) * Status: Open * Priority: Normal * Backport: 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED ---------------------------------------- Consider this `c` object which hash `#succ` method. ```ruby 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. ```ruby (c..c.succ).step(1) do |d| p d.i # 0, 1 end ``` But it fails on an endless range. ```ruby (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>' ``` -- https://bugs.ruby-lang.org/

Issue #19426 has been updated by hsbt (Hiroshi SHIBATA). Backport changed from 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED to 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: DONE ruby_3_2 commit:89eacd31b7565aa45b9c9af4b475cf908830e41c merged revision(s) commit:da4464b824857d7610f9865ceb452ce0ead49164. ---------------------------------------- Bug #19426: Endless `Range#step` of object with `#succ` method does not work https://bugs.ruby-lang.org/issues/19426#change-112280 * Author: nobu (Nobuyoshi Nakada) * Status: Closed * Backport: 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED, 3.2: DONE ---------------------------------------- Consider this `c` object which hash `#succ` method. ```ruby 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. ```ruby (c..c.succ).step(1) do |d| p d.i # 0, 1 end ``` But it fails on an endless range. ```ruby (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>' ``` -- https://bugs.ruby-lang.org/
participants (3)
-
hsbt (Hiroshi SHIBATA)
-
matz (Yukihiro Matsumoto)
-
nobu (Nobuyoshi Nakada)