From 469a0a4a08dc4b3d3b6387b1f569108cc0750f17 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Thu, 13 Mar 2025 13:34:24 +0900 Subject: [PATCH] merge revision(s) da4464b824857d7610f9865ceb452ce0ead49164: [Backport #19426] [Bug #19426] Fix endless `Range#step` with `#succ` method --- range.c | 6 +++++- test/ruby/test_range.rb | 40 ++++++++++++++++++++++++++++++++++++++++ version.h | 2 +- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/range.c b/range.c index a70347eb91..dbc37c1410 100644 --- a/range.c +++ b/range.c @@ -532,7 +532,11 @@ range_step(int argc, VALUE *argv, VALUE range) rb_raise(rb_eTypeError, "can't iterate from %s", rb_obj_classname(b)); } - range_each_func(range, step_i, (VALUE)iter); + if (!NIL_P(e)) + range_each_func(range, step_i, (VALUE)iter); + else + for (;; b = rb_funcallv(b, id_succ, 0, 0)) + step_i(b, (VALUE)iter); } } return range; diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index d84184c3bf..e64a93d9c2 100644 --- a/test/ruby/test_range.rb +++ b/test/ruby/test_range.rb @@ -393,6 +393,26 @@ class TestRange < Test::Unit::TestCase assert_equal(4, (1.0...5.6).step(1.5).to_a.size) end + def test_step_with_succ + c = Struct.new(:i) do + def succ; self.class.new(i+1); end + def <=>(other) i <=> other.i;end + end.new(0) + + result = [] + (c..c.succ).step(2) do |d| + result << d.i + end + assert_equal([0], result) + + result = [] + (c..).step(2) do |d| + result << d.i + break if d.i >= 4 + end + assert_equal([0, 2, 4], result) + end + def test_each a = [] (0..10).each {|x| a << x } @@ -457,6 +477,26 @@ class TestRange < Test::Unit::TestCase assert_equal(["a", "b", "c"], a) end + def test_each_with_succ + c = Struct.new(:i) do + def succ; self.class.new(i+1); end + def <=>(other) i <=> other.i;end + end.new(0) + + result = [] + (c..c.succ).each do |d| + result << d.i + end + assert_equal([0, 1], result) + + result = [] + (c..).each do |d| + result << d.i + break if d.i >= 4 + end + assert_equal([0, 1, 2, 3, 4], result) + end + def test_begin_end assert_equal(0, (0..1).begin) assert_equal(1, (0..1).end) diff --git a/version.h b/version.h index 35bcf3d3eb..0eaf4e5370 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 7 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 261 +#define RUBY_PATCHLEVEL 262 #include "ruby/version.h" #include "ruby/internal/abi.h"