From: akim.demaille@... Date: 2021-01-14T04:55:08+00:00 Subject: [ruby-core:102084] [Ruby master Bug#17537] === on ranges of strings is not consistant with include? Issue #17537 has been updated by akim (Akim Demaille). Ok. Well, my personal opinion is that just to have some fancy way to handle version strings, ranges of strings have inconsistent semantics. With to_a, they behave like their natural order is shortlex on some imaginary alphabet: ``` irb(main):005:0> ('a'..'aa').to_a => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "aa"] ``` but `===` behaves like it's using only the lexical order: ``` irb(main):001:1* case 'ANA' irb(main):002:1* when 'A'..'Z' then puts 1 irb(main):003:1* else puts 2 irb(main):004:0> end 1 => nil ``` If the point was to support version strings, of course that does not work properly in all the cases, just the simple ones. ``` irb(main):001:1* case '2.6.5' irb(main):002:1* when '2.4'..'2.10' irb(main):003:1* puts 'matches' irb(main):004:1* else irb(main):005:1* puts 'nope :(' irb(main):006:0> end nope :( => nil ``` Version strings should be handled, well, with their specific semantics. So you need ranges of Versions. I'm sad that global consistency (ranges have a set-semantics, and === means ���) was sacrificed for some nice-looking-broken-example. Just to be clear: I agree that expecting "6" to be part of "1".."12" is weird (but I really don't think it is less weird to expect "ANA" to be part of "A".."Z".). But at least the language was consistent: "6" is there when one iterates over "1".."12". Cheers! ---------------------------------------- Bug #17537: === on ranges of strings is not consistant with include? https://bugs.ruby-lang.org/issues/17537#change-89942 * 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: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>