8000 [Bug #19426] Fix endless `Range#step` with `#succ` method · github/ruby@da4464b · GitHub
[go: up one dir, main page]

Skip to content

Commit da4464b

Browse files
committed
[Bug #19426] Fix endless Range#step with #succ method
1 parent 8edd350 commit da4464b

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

range.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,11 @@ range_step(int argc, VALUE *argv, VALUE range)
532532
rb_raise(rb_eTypeError, "can't iterate from %s",
533533
rb_obj_classname(b));
534534
}
535-
range_each_func(range, step_i, (VALUE)iter);
535+
if (!NIL_P(e))
536+
range_each_func(range, step_i, (VALUE)iter);
537+
else
538+
for (;; b = rb_funcallv(b, id_succ, 0, 0))
539+
step_i(b, (VALUE)iter);
536540
}
537541
}
538542
return range;

test/ruby/test_range.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,26 @@ def test_step_ruby_core_35753
392392
assert_equal(4, (1.0...5.6).step(1.5).to_a.size)
393393
end
394394

395+
def test_step_with_succ
396+
c = Struct.new(:i) do
397+
def succ; self.class.new(i+1); end
398+
def <=>(other) i <=> other.i;end
399+
end.new(0)
400+
401+
result = []
402+
(c..c.succ).step(2) do |d|
403+
result << d.i
404+
end
405+
assert_equal([0], result)
406+
407+
result = []
408+
(c..).step(2) do |d|
409+
result << d.i
410+
break if d.i >= 4
411+
end
412+
assert_equal([0, 2, 4], result)
413+
end
414+
395415
def test_each
396416
a = []
397417
(0..10).each {|x| a << x }
@@ -456,6 +476,26 @@ def <=>(other) to_str <=> other end
456476
assert_equal(["a", "b", "c"], a)
457477
end
458478

479+
def test_each_with_succ
480+
c = Struct.new(:i) do
481+
def succ; self.class.new(i+1); end
482+
def <=>(other) i <=> other.i;end
483+
end.new(0)
484+
485+
result = []
486+
(c..c.succ).each do |d|
487+
result << d.i
488+
end
489+
assert_equal([0, 1], result)
490+
491+
result = []
492+
(c..).each do |d|
493+
result << d.i
494+
break if d.i >= 4
495+
end
496+
assert_equal([0, 1, 2, 3, 4], result)
497+
end
498+
459499
def test_begin_end
460500
assert_equal(0, (0..1).begin)
461501
assert_equal(1, (0..1).end)

0 commit comments

Comments
 (0)
0