Skip to content

Commit 24b0501

Browse files
nirvdrumclaude
authored andcommitted
Fix Range#step clamping for negative steps with Float entries.
The clamping logic that corrects floating-point overshoot on the final iteration only handled positive steps. For negative steps (descending float ranges), the comparison needs to be reversed. Also adds specs for negative `Float` steps. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e44bba4 commit 24b0501

1 file changed

Lines changed: 21 additions & 7 deletions

File tree

core/range/step_spec.rb

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,10 @@
6565
end
6666

6767
ruby_version_is "3.4" do
68-
it "does not raise an ArgumentError if step is 0 for non-numeric ranges" do
69-
t = Time.utc(2023, 2, 24)
70-
-> { (t..t+1).step(0) { break } }.should_not raise_error(ArgumentError)
71-
end
72-
73-
it "does not iterate if step does not move values for bounded non-numeric ranges" do
68+
it "does not iterate if step is 0 for bounded non-numeric ranges" do
7469
t = Time.utc(2023, 2, 24)
7570
(t..t + 1).step(0) { |x| ScratchPad << x }
76-
ScratchPad.recorded.should eql([])
71+
ScratchPad.recorded.should == []
7772
end
7873

7974
it "raises an ArgumentError when iterating a beginless range" do
@@ -149,6 +144,18 @@
149144
(0.0..Float::INFINITY).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
150145
ScratchPad.recorded.should eql([0.0, 2.0, 4.0])
151146
end
147+
148+
ruby_version_is "3.4" do
149+
it "does not iterate if step is negative for forward range" do
150+
(-1.0..1.0).step(-0.5) { |x| ScratchPad << x }
151+
ScratchPad.recorded.should eql([])
152+
end
153+
154+
it "iterates backward if step is negative for backward range" do
155+
(1.0..-1.0).step(-0.5) { |x| ScratchPad << x }
156+
ScratchPad.recorded.should eql([1.0, 0.5, 0.0, -0.5, -1.0])
157+
end
158+
end
152159
end
153160

154161
describe "and Integer, Float values" do
@@ -348,6 +355,13 @@
348355
(0.0...Float::INFINITY).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
349356
ScratchPad.recorded.should eql([0.0, 2.0, 4.0])
350357
end
358+
359+
ruby_version_is "3.4" do
360+
it "iterates backward with exclusive end if step is negative" do
361+
(1.0...-1.0).step(-0.5) { |x| ScratchPad << x }
362+
ScratchPad.recorded.should eql([1.0, 0.5, 0.0, -0.5])
363+
end
364+
end
351365
end
352366

353367
describe "and Integer, Float values" do

0 commit comments

Comments
 (0)