Project

General

Profile

Actions

Bug #19533

closed

Behavior of ===/include? on a beginless/endless range (nil..nil) changed in ruby 3.2

Added by knu (Akinori MUSHA) about 1 year ago. Updated 9 months ago.

Status:
Closed
Assignee:
-
Target version:
ruby -v:
ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-darwin22]
[ruby-core:112922]

Description

Starting from Ruby 2.7.0 a range nil..nil used to match any value until 3.2.0-preview3, but 3.2.0-rc1 started to reject it.

% docker run -it --rm rubylang/all-ruby ./all-ruby -e 'p( (nil..nil) === 1 )'
(snip)
ruby-2.6.10           false
ruby-2.7.0-preview1   true
...
ruby-3.2.0-preview3   true
ruby-3.2.0-rc1        -e:1:in `===': cannot determine inclusion in beginless/endless ranges (TypeError)

                      p( (nil..nil) === 1 )
                                        ^
                        from -e:1:in `<main>'
                  exit 1
...
ruby-3.2.1            -e:1:in `===': cannot determine inclusion in beginless/endless ranges (TypeError)

                      p( (nil..nil) === 1 )
                                        ^
                        from -e:1:in `<main>'

The previous behavior was so useful because when you have optional lower and upper bounds lbound..rbound would always work regardless of each end being nil or not.

There is no mention of this in doc/NEWS/NEWS-3.2.0.md, so I'm afraid it was caused unintentionally while fixing other problems.

% docker run -it --rm rubylang/all-ruby ./all-ruby -e 'p( (nil..nil).cover?(1) )'
(snip)
ruby-2.6.10           false
ruby-2.7.0-preview1   true
...
ruby-3.2.1            true

This was pointed out by the following blog article (written in Japanese) as a "pitfall" that you need to work around when upgrading Ruby from 3.0/3.1 to 3.2.
https://blog.studysapuri.jp/entry/2023/03/16/ujihisa-ruby32#endless-range%E3%81%AE%E6%8C%99%E5%8B%95%E3%81%AE%E5%A4%89%E6%9B%B4


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #18580: Range#include? inconsistency for beginless String rangesClosedActions
Actions #1

Updated by mame (Yusuke Endoh) about 1 year ago

  • Related to Bug #18580: Range#include? inconsistency for beginless String ranges added

Updated by mame (Yusuke Endoh) about 1 year ago

In #18580, @matz (Yukihiro Matsumoto) said:

I decided to make include? to raise exception for beginless/endless non-numeric ranges.

and (nil..nil) is considered as a non-numeric range.

Updated by knu (Akinori MUSHA) about 1 year ago

mame (Yusuke Endoh) wrote in #note-2:

In #18580, @matz (Yukihiro Matsumoto) said:

I decided to make include? to raise exception for beginless/endless non-numeric ranges.

and (nil..nil) is considered as a non-numeric range.

Thanks for the info. This hurts not only because the behavior changed without notice (in the NEWS file) but because it broke the useful feature. Before the change, you could just say scores.grep(min..max) when min and max are both optional, but now you need to check if min and max are both nil and branch the logic.

While (nil..nil) === value (used in case, Enumerable#grep, any?, etc.) no longer works, ActiveRecord queries like Product.where(price: min..max) still work because === is not used there. This is a bit confusing and hard to explain why.

I'm not absolutely sure about include?, but as for === I'd like the previous behavior to be restored because it was so useful and aligned with cover?, and changing back wouldn't break existing code because the current behavior is to raise an error rather than returning false.

Updated by matz (Yukihiro Matsumoto) 12 months ago

It is an unintentional behavior. I agree to fix nil .. nil case.

Matz.

Actions #6

Updated by nobu (Nobuyoshi Nakada) 12 months ago

  • Backport changed from 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN to 2.7: DONTNEED, 3.0: DONTNEED, 3.1: DONTNEED, 3.2: REQUIRED
Actions #7

Updated by nobu (Nobuyoshi Nakada) 12 months ago

  • Status changed from Open to Closed

Applied in changeset git|fb17c833f542222afdf482924877d43aa577782d.


[Bug #19533] Fix infinite range inclusion with numeric value

Updated by nagachika (Tomoyuki Chikanaga) 9 months ago

  • Backport changed from 2.7: DONTNEED, 3.0: DONTNEED, 3.1: DONTNEED, 3.2: REQUIRED to 2.7: DONTNEED, 3.0: DONTNEED, 3.1: DONTNEED, 3.2: DONE

ruby_3_2 5328c58c7d00540f4f56749aaeefb68761bd7eba merged revision(s) 1a149aab776aa6741628eb35482eff1ded197fd2,fb17c833f542222afdf482924877d43aa577782d,60f22ebf86248388b41b4ec751d16700f2b4b621.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0