Actions
Bug #16450
closedRange#min with a beginless range should raise an explicit exception
Description
Range#max with an endless range raises an explicit exception, so Range#min with a beginless range do the same.
$ ruby -e '(0..).max'
Traceback (most recent call last):
1: from -e:1:in `<main>'
-e:1:in `max': cannot get the maximum of endless range (RangeError)
$ ruby -e '(..0).min'
Traceback (most recent call last):
1: from -e:1:in `<main>'
-e:1:in `min': comparison of NilClass with 0 failed (ArgumentError)
Range#max with a block has a similar issue.
$ ruby -e '(0..).min {|a,b| a }'
Traceback (most recent call last):
1: from -e:1:in `<main>'
-e:1:in `min': cannot get the minimum of endless range with custom comparison method (RangeError)
$ ruby -e '(..0).max {|a,b| a }'
Traceback (most recent call last):
3: from -e:1:in `<main>'
2: from -e:1:in `max'
1: from -e:1:in `max'
-e:1:in `each': can't iterate from NilClass (TypeError)
diff --git a/range.c b/range.c
index fe956197c6..bf14c0c7a7 100644
--- a/range.c
+++ b/range.c
@@ -1136,6 +1136,10 @@ range_last(int argc, VALUE *argv, VALUE range)
static VALUE
range_min(int argc, VALUE *argv, VALUE range)
{
+ if (NIL_P(RANGE_BEG(range))) {
+ rb_raise(rb_eRangeError, "cannot get the minimum of beginless range");
+ }
+
if (rb_block_given_p()) {
if (NIL_P(RANGE_END(range))) {
rb_raise(rb_eRangeError, "cannot get the minimum of endless range with custom comparison method");
@@ -1185,6 +1189,9 @@ range_max(int argc, VALUE *argv, VALUE range)
}
if (rb_block_given_p() || (EXCL(range) && !nm) || argc) {
+ if (NIL_P(RANGE_BEG(range))) {
+ rb_raise(rb_eRangeError, "cannot get the maximum of beginless range with custom comparison method");
+ }
return rb_call_super(argc, argv);
}
else {
diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb
index 800cee92cc..b37dbbc433 100644
--- a/test/ruby/test_range.rb
+++ b/test/ruby/test_range.rb
@@ -81,6 +81,8 @@ def test_min
assert_equal(nil, (2..1).min)
assert_equal(1, (1...2).min)
assert_equal(1, (1..).min)
+ assert_raise(RangeError) { (..1).min }
+ assert_raise(RangeError) { (...1).min }
assert_equal(1.0, (1.0..2.0).min)
assert_equal(nil, (2.0..1.0).min)
@@ -93,6 +95,8 @@ def test_min
assert_equal([0,1,2], (0..10).min(3))
assert_equal([0,1], (0..1).min(3))
assert_equal([0,1,2], (0..).min(3))
+ assert_raise(RangeError) { (..1).min(3) }
+ assert_raise(RangeError) { (...1).min(3) }
assert_raise(RangeError) { (0..).min {|a, b| a <=> b } }
end
@@ -119,6 +123,8 @@ def test_max
assert_equal([9,8,7], (0...10).max(3))
assert_raise(RangeError) { (1..).max(3) }
assert_raise(RangeError) { (1...).max(3) }
+
+ assert_raise(RangeError) { (..0).min {|a, b| a <=> b } }
end
def test_minmax
Actions
Like0
Like0