[ruby-core:114641] [Ruby master Bug#19864] Ruby 3.2 Changed Behavior With One Sided Ranges

Issue #19864 has been reported by Aesthetikx (John DeSilva). ---------------------------------------- Bug #19864: Ruby 3.2 Changed Behavior With One Sided Ranges https://bugs.ruby-lang.org/issues/19864 * Author: Aesthetikx (John DeSilva) * Status: Open * Priority: Normal * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Thank you for taking the time to read my issue. I know there has been some previous discussion here https://bugs.ruby-lang.org/issues/19533 regarding a similar issue, although I think this is different. I apologize if this has already been addressed. Prior to Ruby 3.2, you could use a beginless or endless range, and use === (or a case statement) to determine if a given date matched that range. For example, (..today) === yesterday would have returned true, and (tomorrow..) === today would have returned false. Please see my attached file for a more concrete example. Starting with Ruby 3.2, this results in "`===': cannot determine inclusion in beginless/endless ranges (TypeError)". I can imagine that there is difficulty and ambiguity with these infinite ranges and non numeric objects, however I do feel that these examples with dates should work, especially since (..Date.today).cover?(Date.today) still works as expected. ---Files-------------------------------- range_test.rb (928 Bytes) -- https://bugs.ruby-lang.org/

Issue #19864 has been updated by jgomo3 (Jesús Gómez). File range_test_2.rb added File range_test_3.rb added I tested the idea with whole numbers, and it doesn't fail. I tested the idea with dates not in the extremes, and it DOES fail. Attached 2 examples. The first one using numbers: ``` (..0) === 0 ``` Which works fine both in Ruby 3.1 and 3.2 The second one using different dates. In particular, checking if "yesterday" is in the range of "..today": ``` require 'date' today = Date.today yesterday = today - 1 (..today) === yesterday ``` And it fails in 3.2, but works fine in 3.1. ---------------------------------------- Bug #19864: Ruby 3.2 Changed Behavior With One Sided Ranges https://bugs.ruby-lang.org/issues/19864#change-104482 * Author: Aesthetikx (John DeSilva) * Status: Open * Priority: Normal * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Thank you for taking the time to read my issue. I know there has been some previous discussion here https://bugs.ruby-lang.org/issues/19533 regarding a similar issue, although I think this is different. I apologize if this has already been addressed. Prior to Ruby 3.2, you could use a beginless or endless range, and use === (or a case statement) to determine if a given date matched that range. For example, (..today) === yesterday would have returned true, and (tomorrow..) === today would have returned false. Please see my attached file for a more concrete example. Starting with Ruby 3.2, this results in "`===': cannot determine inclusion in beginless/endless ranges (TypeError)". I can imagine that there is difficulty and ambiguity with these infinite ranges and non numeric objects, however I do feel that these examples with dates should work, especially since (..Date.today).cover?(Date.today) still works as expected. ---Files-------------------------------- range_test.rb (928 Bytes) range_test_2.rb (411 Bytes) range_test_3.rb (162 Bytes) -- https://bugs.ruby-lang.org/

Issue #19864 has been updated by zverok (Victor Shepelev). Seems to be a bug indeed. Originates from [this commit](https://github.com/ruby/ruby/commit/04a92a6764bf678919cf4b68a27496a39d6b886a), which fixed behavior for semi-open Ranges `#include?` but also [added semi-openness](https://github.com/ruby/ruby/commit/04a92a6764bf678919cf4b68a27496a39d6b886a...) check to `range_string_cover_internal`. cc @jeremyevans0 ---------------------------------------- Bug #19864: Ruby 3.2 Changed Behavior With One Sided Ranges https://bugs.ruby-lang.org/issues/19864#change-104483 * Author: Aesthetikx (John DeSilva) * Status: Open * Priority: Normal * ruby -v: 3.3.0 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Thank you for taking the time to read my issue. I know there has been some previous discussion here https://bugs.ruby-lang.org/issues/19533 regarding a similar issue, although I think this is different. I apologize if this has already been addressed. Prior to Ruby 3.2, you could use a beginless or endless range, and use === (or a case statement) to determine if a given date matched that range. For example, (..today) === yesterday would have returned true, and (tomorrow..) === today would have returned false. Please see my attached file for a more concrete example. Starting with Ruby 3.2, this results in "`===': cannot determine inclusion in beginless/endless ranges (TypeError)". I can imagine that there is difficulty and ambiguity with these infinite ranges and non numeric objects, however I do feel that these examples with dates should work, especially since (..Date.today).cover?(Date.today) still works as expected. ---Files-------------------------------- range_test.rb (928 Bytes) range_test_2.rb (411 Bytes) range_test_3.rb (162 Bytes) -- https://bugs.ruby-lang.org/

Issue #19864 has been updated by jeremyevans0 (Jeremy Evans). This appears to fix it: ```diff diff --git a/range.c b/range.c index 62e957e622..4b2e2460c7 100644 --- a/range.c +++ b/range.c @@ -1818,6 +1818,7 @@ range_string_cover_internal(VALUE range, VALUE val) return r_cover_p(range, beg, end, val); } if (NIL_P(beg)) { +unbounded_begin:; VALUE r = rb_funcall(val, id_cmp, 1, end); if (NIL_P(r)) return Qfalse; if (RANGE_EXCL(range)) { @@ -1826,12 +1827,20 @@ range_string_cover_internal(VALUE range, VALUE val) return RBOOL(rb_cmpint(r, val, end) <= 0); } else if (NIL_P(end)) { +unbounded_end:; VALUE r = rb_funcall(beg, id_cmp, 1, val); if (NIL_P(r)) return Qfalse; return RBOOL(rb_cmpint(r, beg, val) <= 0); } } + if (!NIL_P(beg) && NIL_P(end)) { + goto unbounded_end; + } + if (NIL_P(beg) && !NIL_P(end)) { + goto unbounded_begin; + } + return range_include_fallback(beg, end, val); } ``` I'll try to add tests and submit a pull request within a week. ---------------------------------------- Bug #19864: Ruby 3.2 Changed Behavior With One Sided Ranges https://bugs.ruby-lang.org/issues/19864#change-104485 * Author: Aesthetikx (John DeSilva) * Status: Open * Priority: Normal * ruby -v: 3.3.0 * Backport: 3.0: DONTNEED, 3.1: DONTNEED, 3.2: REQUIRED ---------------------------------------- Thank you for taking the time to read my issue. I know there has been some previous discussion here https://bugs.ruby-lang.org/issues/19533 regarding a similar issue, although I think this is different. I apologize if this has already been addressed. Prior to Ruby 3.2, you could use a beginless or endless range, and use === (or a case statement) to determine if a given date matched that range. For example, (..today) === yesterday would have returned true, and (tomorrow..) === today would have returned false. Please see my attached file for a more concrete example. Starting with Ruby 3.2, this results in "`===': cannot determine inclusion in beginless/endless ranges (TypeError)". I can imagine that there is difficulty and ambiguity with these infinite ranges and non numeric objects, however I do feel that these examples with dates should work, especially since (..Date.today).cover?(Date.today) still works as expected. ---Files-------------------------------- range_test.rb (928 Bytes) range_test_2.rb (411 Bytes) range_test_3.rb (162 Bytes) -- https://bugs.ruby-lang.org/

Issue #19864 has been updated by jeremyevans0 (Jeremy Evans). I've submitted a pull request for the diff posted earlier (with tests): https://github.com/ruby/ruby/pull/8458 ---------------------------------------- Bug #19864: Ruby 3.2 Changed Behavior With One Sided Ranges https://bugs.ruby-lang.org/issues/19864#change-104626 * Author: Aesthetikx (John DeSilva) * Status: Open * Priority: Normal * ruby -v: 3.3.0 * Backport: 3.0: DONTNEED, 3.1: DONTNEED, 3.2: REQUIRED ---------------------------------------- Thank you for taking the time to read my issue. I know there has been some previous discussion here https://bugs.ruby-lang.org/issues/19533 regarding a similar issue, although I think this is different. I apologize if this has already been addressed. Prior to Ruby 3.2, you could use a beginless or endless range, and use === (or a case statement) to determine if a given date matched that range. For example, (..today) === yesterday would have returned true, and (tomorrow..) === today would have returned false. Please see my attached file for a more concrete example. Starting with Ruby 3.2, this results in "`===': cannot determine inclusion in beginless/endless ranges (TypeError)". I can imagine that there is difficulty and ambiguity with these infinite ranges and non numeric objects, however I do feel that these examples with dates should work, especially since (..Date.today).cover?(Date.today) still works as expected. ---Files-------------------------------- range_test.rb (928 Bytes) range_test_2.rb (411 Bytes) range_test_3.rb (162 Bytes) -- https://bugs.ruby-lang.org/

Issue #19864 has been updated by nagachika (Tomoyuki Chikanaga). Backport changed from 3.0: DONTNEED, 3.1: DONTNEED, 3.2: REQUIRED to 3.0: DONTNEED, 3.1: DONTNEED, 3.2: DONE ruby_3_2 217ef2bf89b3861e83c2e2a3a633c019f0731de6 merged revision(s) 25711683e86271385e8abe09a9c03782000e48db. ---------------------------------------- Bug #19864: Ruby 3.2 Changed Behavior With One Sided Ranges https://bugs.ruby-lang.org/issues/19864#change-104751 * Author: Aesthetikx (John DeSilva) * Status: Closed * Priority: Normal * ruby -v: 3.3.0 * Backport: 3.0: DONTNEED, 3.1: DONTNEED, 3.2: DONE ---------------------------------------- Thank you for taking the time to read my issue. I know there has been some previous discussion here https://bugs.ruby-lang.org/issues/19533 regarding a similar issue, although I think this is different. I apologize if this has already been addressed. Prior to Ruby 3.2, you could use a beginless or endless range, and use === (or a case statement) to determine if a given date matched that range. For example, (..today) === yesterday would have returned true, and (tomorrow..) === today would have returned false. Please see my attached file for a more concrete example. Starting with Ruby 3.2, this results in "`===': cannot determine inclusion in beginless/endless ranges (TypeError)". I can imagine that there is difficulty and ambiguity with these infinite ranges and non numeric objects, however I do feel that these examples with dates should work, especially since (..Date.today).cover?(Date.today) still works as expected. ---Files-------------------------------- range_test.rb (928 Bytes) range_test_2.rb (411 Bytes) range_test_3.rb (162 Bytes) -- https://bugs.ruby-lang.org/
participants (5)
-
Aesthetikx (John DeSilva)
-
jeremyevans0 (Jeremy Evans)
-
jgomo3
-
nagachika (Tomoyuki Chikanaga)
-
zverok (Victor Shepelev)