Issue #19533 has been updated by knu (Akinori MUSHA).
mame (Yusuke Endoh) wrote in #note-2:
In #18580, @matz 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.
----------------------------------------
Bug #19533: Behavior of ===/include? on a beginless/endless range (nil..nil) changed in
ruby 3.2
https://bugs.ruby-lang.org/issues/19533#change-102447
* Author: knu (Akinori MUSHA)
* Status: Open
* Priority: Normal
* Target version: 3.2
* ruby -v: ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-darwin22]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
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%E…
--
https://bugs.ruby-lang.org/