From: zverok.offline@... Date: 2021-01-13T17:35:26+00:00 Subject: [ruby-core:102068] [Ruby master Bug#17537] === on ranges of strings is not consistant with include? Issue #17537 has been updated by zverok (Victor Shepelev). It was intentional. Before 2.6, `===` was using `include?` underneath, which had some undesirable consequences: ```ruby case '2.5.2' when '2.5'..'2.6' puts "It is between 2.5 and 2.6" else puts "It is not" end ``` This prints `"It is between 2.6 and 2.6"` in Ruby 2.7, but prints `"It is not"` on 2.5. It seems that "logically" the former is right. So, in Ruby 2.6, `===` [was changed to use `cover?`](https://rubyreferences.github.io/rubychanges/2.6.html#range-uses-cover-instead-of-include) -- but, somehow, not for strings. It was considered an oversight and was [changed in 2.7](https://rubyreferences.github.io/rubychanges/2.7.html#for-string). ```ruby case "6" when "1".."12" # ... ``` ...is somewhat semantically "wrong" (you are expecting to strings being compared by their numeric values), but strings are tricky, and I agree there are many edge cases which can be considered "weird"/"inconsistent", there are several tickets (I don't remember the numbers by heart) complaining about strings being between the range ends, but not in the range's items list, or vice versa. ---------------------------------------- Bug #17537: === on ranges of strings is not consistant with include? https://bugs.ruby-lang.org/issues/17537#change-89929 * Author: akim (Akim Demaille) * Status: Open * Priority: Normal * ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin18] * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN ---------------------------------------- Hi, In Ruby up to 2.6 both `("1".."12").include?("6")` and `("1".."12") === "6"` were true. In 2.7 and 3.0, `include?` accepts `"6"`, but `===` does not. This was very handy in `case`s. Reading the documentation it is unclear to me whether this change was intentional. ``` $ cat /tmp/foo.rb puts(("1".."12").include?("6")) puts(("1".."12") === "6") p(("1".."12").to_a) $ ruby2.6 /tmp/foo.rb true true ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"] $ ruby2.7 /tmp/foo.rb true false ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"] $ ruby3.0 /tmp/foo.rb true false ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"] ``` Cheers! -- https://bugs.ruby-lang.org/ Unsubscribe: