Fix non-numeric exclusive Range#minmax bug
The implementation of Range#minmax added in d5c60214c45 causes the following incorrect behaviour: ('a'...'c').minmax => ["a", ["a", "b"]] instead of ('a'...'c').minmax => ["a", "b"] 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. Perhaps it is possible to change the execution context in an optimized manner, but the simplest solution seems to be to just explicitly delegate from Range#minmax to Range#min and Range#max.
This commit is contained in:
parent
9fc564cfef
commit
bf1a6771f3
Notes:
git
2020-07-05 02:02:57 +09:00
5
range.c
5
range.c
@ -1266,7 +1266,10 @@ range_minmax(VALUE range)
|
||||
if (rb_block_given_p()) {
|
||||
return rb_call_super(0, NULL);
|
||||
}
|
||||
return rb_assoc_new(range_min(0, NULL, range), range_max(0, NULL, range));
|
||||
return rb_assoc_new(
|
||||
rb_funcall(range, rb_intern("min"), 0),
|
||||
rb_funcall(range, rb_intern("max"), 0)
|
||||
);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -146,6 +146,9 @@ class TestRange < Test::Unit::TestCase
|
||||
assert_equal([nil, nil], (0...0).minmax)
|
||||
|
||||
assert_equal([2, 1], (1..2).minmax{|a, b| b <=> a})
|
||||
|
||||
assert_equal(['a', 'c'], ('a'..'c').minmax)
|
||||
assert_equal(['a', 'b'], ('a'...'c').minmax)
|
||||
end
|
||||
|
||||
def test_initialize_twice
|
||||
|
Loading…
x
Reference in New Issue
Block a user