diff --git a/CHANGELOG.md b/CHANGELOG.md index 18d0209ce4cd..22d4cc9be4a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ Compatibility: * Fix arguments implicit type conversion for `Enumerable#zip` and `Array#zip` (#2788, @andrykonchin). * Fix `Array#unshift` to not depend on `Array#[]=` and allow overriding `#[]=` in a subclass (#2772, @andrykonchin). * Fix syntactic check for `void value expression` (#2821, @eregon). +* Fix `Range#step` with no block and non-`Numeric` values (#2824, @eregon). Performance: diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb index 61ddc5205d4b..9024636d5556 100644 --- a/spec/ruby/core/range/step_spec.rb +++ b/spec/ruby/core/range/step_spec.rb @@ -474,10 +474,14 @@ end end + # We use .take below to ensure the enumerator works + # because that's an Enumerable method and so it uses the Enumerator behavior + # not just a method overridden in Enumerator::ArithmeticSequence. describe "type" do context "when both begin and end are numerics" do it "returns an instance of Enumerator::ArithmeticSequence" do (1..10).step.class.should == Enumerator::ArithmeticSequence + (1..10).step(3).take(4).should == [1, 4, 7, 10] end end @@ -490,10 +494,12 @@ context "when range is endless" do it "returns an instance of Enumerator::ArithmeticSequence when begin is numeric" do (1..).step.class.should == Enumerator::ArithmeticSequence + (1..).step(2).take(3).should == [1, 3, 5] end it "returns an instance of Enumerator when begin is not numeric" do ("a"..).step.class.should == Enumerator + ("a"..).step(2).take(3).should == %w[a c e] end end @@ -506,6 +512,7 @@ context "when begin and end are not numerics" do it "returns an instance of Enumerator" do ("a".."z").step.class.should == Enumerator + ("a".."z").step(3).take(4).should == %w[a d g j] end end end diff --git a/src/main/ruby/truffleruby/core/truffle/range_operations.rb b/src/main/ruby/truffleruby/core/truffle/range_operations.rb index 81659b129154..2dc84d5398e3 100644 --- a/src/main/ruby/truffleruby/core/truffle/range_operations.rb +++ b/src/main/ruby/truffleruby/core/truffle/range_operations.rb @@ -41,7 +41,7 @@ def self.step_no_block(range, step_size) if arithmetic_range?(from, to) Enumerator::ArithmeticSequence.new(range, :step, from, to, step_size, range.exclude_end?) else - to_enum(:step, step_size) do + range.to_enum(:step, step_size) do validated_step_args = validate_step_size(from, to, step_size) step_iterations_size(range, *validated_step_args) end