ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:99071] [Ruby master Bug#17014] Range#minmax returns incorrect results on non-numeric exclusive ranges
@ 2020-07-05 16:42 bosticko
  2020-07-19  3:16 ` [ruby-core:99220] " nagachika00
  0 siblings, 1 reply; 2+ messages in thread
From: bosticko @ 2020-07-05 16:42 UTC (permalink / raw
  To: ruby-core

Issue #17014 has been reported by sambostock (Sam Bostock).

----------------------------------------
Bug #17014: Range#minmax returns incorrect results on non-numeric exclusive ranges
https://bugs.ruby-lang.org/issues/17014

* Author: sambostock (Sam Bostock)
* Status: Open
* Priority: Normal
* ruby -v: 2.7.1
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
The implementation of `Range#minmax` added in [d5c60214c45](https://github.com/ruby/ruby/commit/d5c60214c45bafc1cf2a516f852394986f9c84bb) causes the following incorrect behaviour:

```ruby
('a'...'c').minmax # => ["a", ["a", "b"]]
```


instead of

```ruby
('a'...'c').minmax # => ["a", "b"]
```

### Cause

This is because the C implementation of `Range#minmax` (`range_minmax`) directly delegates to the C implementation of `Range#min` (`range_min`) and `Range#max` (`range_max`), without changing the execution context.

`Range#max`'s C implementation (`range_max`), when given a non-numeric exclusive range, delegates to `super`, which is meant to call `Enumerable#max`. However, because `range_max` is called directly by `range_minmax`, `super` calls `Enumerable#minmax` instead, causing the incorrect nesting.

### Resolution

- [ruby/ruby#3285](https://github.com/ruby/ruby/pull/3285) fixed this bug by explicitly calling `Range#min` and `Range#max`, instead of delegating **directly** to `range_min` and `range_max`
- [ruby/ruby#3286](https://github.com/ruby/ruby/pull/3286) followed up by replacing `rb_intern("min")` and `rb_intern("max")` in the new implementation with statics `id_min` and `id_max`
- [ruby/ruby#3290](https://github.com/ruby/ruby/pull/3290) follows up by extracting `range_min_internal` and `range_max_internal` from `range_min` and `range_max`, and calling those directly from `range_minmax`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [ruby-core:99220] [Ruby master Bug#17014] Range#minmax returns incorrect results on non-numeric exclusive ranges
  2020-07-05 16:42 [ruby-core:99071] [Ruby master Bug#17014] Range#minmax returns incorrect results on non-numeric exclusive ranges bosticko
@ 2020-07-19  3:16 ` nagachika00
  0 siblings, 0 replies; 2+ messages in thread
From: nagachika00 @ 2020-07-19  3:16 UTC (permalink / raw
  To: ruby-core

Issue #17014 has been updated by nagachika (Tomoyuki Chikanaga).

Backport changed from 2.5: DONTNEED, 2.6: DONTNEED, 2.7: REQUIRED to 2.5: DONTNEED, 2.6: DONTNEED, 2.7: DONE

ruby_2_7 d24cce8e7f48b0b45f726f5f1ac7ff796f46ba72 merged revision(s) bf1a6771f305ea286a3ae575676924551c03e857,c1463625555b061a2b94c3b6c5581730b482a285.

----------------------------------------
Bug #17014: Range#minmax returns incorrect results on non-numeric exclusive ranges
https://bugs.ruby-lang.org/issues/17014#change-86601

* Author: sambostock (Sam Bostock)
* Status: Closed
* Priority: Normal
* ruby -v: 2.7.1
* Backport: 2.5: DONTNEED, 2.6: DONTNEED, 2.7: DONE
----------------------------------------
The implementation of `Range#minmax` added in [d5c60214c45](https://github.com/ruby/ruby/commit/d5c60214c45bafc1cf2a516f852394986f9c84bb) causes the following incorrect behaviour:

```ruby
('a'...'c').minmax # => ["a", ["a", "b"]]
```


instead of

```ruby
('a'...'c').minmax # => ["a", "b"]
```

### Cause

This is because the C implementation of `Range#minmax` (`range_minmax`) directly delegates to the C implementation of `Range#min` (`range_min`) and `Range#max` (`range_max`), without changing the execution context.

`Range#max`'s C implementation (`range_max`), when given a non-numeric exclusive range, delegates to `super`, which is meant to call `Enumerable#max`. However, because `range_max` is called directly by `range_minmax`, `super` calls `Enumerable#minmax` instead, causing the incorrect nesting.

### Resolution

- [ruby/ruby#3285](https://github.com/ruby/ruby/pull/3285) fixed this bug by explicitly calling `Range#min` and `Range#max`, instead of delegating **directly** to `range_min` and `range_max`
- [ruby/ruby#3286](https://github.com/ruby/ruby/pull/3286) followed up by replacing `rb_intern("min")` and `rb_intern("max")` in the new implementation with statics `id_min` and `id_max`
- [ruby/ruby#3290](https://github.com/ruby/ruby/pull/3290) follows up by extracting `range_min_internal` and `range_max_internal` from `range_min` and `range_max`, and calling those directly from `range_minmax`



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-07-19  3:16 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-05 16:42 [ruby-core:99071] [Ruby master Bug#17014] Range#minmax returns incorrect results on non-numeric exclusive ranges bosticko
2020-07-19  3:16 ` [ruby-core:99220] " nagachika00

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).