From: "johnnyshields (Johnny Shields) via ruby-core" <ruby-core@...>
Date: 2025-01-12T23:15:58+00:00
Subject: [ruby-core:120625] [Ruby master Bug#21030] Bug: #step with Range<ActiveSupport::Duration> behavior broken on Ruby 3.4.1

Issue #21030 has been updated by johnnyshields (Johnny Shields).


May I confirm this will be patched in Ruby 3.4.2?

----------------------------------------
Bug #21030: Bug: #step with Range<ActiveSupport::Duration> behavior broken on Ruby 3.4.1
https://bugs.ruby-lang.org/issues/21030#change-111455

* Author: johnnyshields (Johnny Shields)
* Status: Closed
* Assignee: zverok (Victor Shepelev)
* Backport: 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED, 3.4: UNKNOWN
----------------------------------------
Issue also filed at: https://github.com/rails/rails/issues/54199

### System configuration
**Rails version**: 7.1.5.1
**Ruby version**: 3.3.4 (works) vs 3.4.1 (broken)

### What's broken

Calling `#step` then `#to_a` on a `Range` whose beginning/end values are the same is expected to return an `Array` wrapping the `Range`'s singular value. In other words, `(x..x).step(n).to_a` should return `[x]` -- note this is also the same as `(x..x).to_a`

The following case breaks on Ruby 3.4.1 related to `ActiveSupport::Duration` class, where it returns an empty array. It works on Ruby 3.3. Both tested with Rails 7.1.5.1. It's very easy to reproduce.

I'm unsure if this is a Ruby bug or a Rails bug so I'm filing it in both places. The upgrade of Ruby is what produces the difference.

```ruby
require 'active_support/all' # version 7.1.5.1

int = 100
dur = 100.seconds # ActiveSupport/Duration

# The bug

(dur..dur).step(10).to_a  # => Ruby 3.3 returns [100 seconds] - CORRECT
                          # => Ruby 3.4 returns [] - INCORRECT

(int..dur).step(10).to_a  # => Ruby 3.3 returns [100] - CORRECT
                          # => Ruby 3.4 returns [] - INCORRECT

# Note the following cases work correctly on both Ruby versions:
(int..int).step(10).to_a  #=> [100]
(int..dur).to_a           #=> [100]

# Range with non-equivalent values also works fine on different versions:
dur2 = 120.seconds
(dur..dur2).step(10).to_a  #=> [100 seconds, 110 seconds, 120 seconds]
(int..dur2).step(10).to_a  #=> [100, 110, 120]
```



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/