Bug #21030
closedBug: #step with Range<ActiveSupport::Duration> behavior broken on Ruby 3.4.1
Description
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.
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]
Updated by zverok (Victor Shepelev) 9 days ago
- Assignee set to zverok (Victor Shepelev)
- Backport changed from 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN to 3.1: DONTNEED, 3.2: DONTNEED, 3.3: DONTNEED, 3.4: UNKNOWN
Updated by zverok (Victor Shepelev) 9 days ago
Confirmed, looking into it.
Updated by nobu (Nobuyoshi Nakada) 9 days ago
- Status changed from Open to Closed
Applied in changeset git|f56f3eaae55cc6f8d9e79862ee73a9ffb53d6077.
[Bug #21030] Fix step for non-numeric range
When the end points of an inclusive range equal, Range#step
should
yields the element once.
Updated by johnnyshields (Johnny Shields) 8 days ago
May I confirm this will be patched in Ruby 3.4.2?
Updated by nobu (Nobuyoshi Nakada) 8 days ago
3.4.2 is not scheduled yet.