diff options
-rw-r--r-- | range.c | 22 | ||||
-rw-r--r-- | test/ruby/test_range.rb | 21 |
2 files changed, 43 insertions, 0 deletions
@@ -1211,6 +1211,27 @@ range_max(int argc, VALUE *argv, VALUE range) } } +/* + * call-seq: + * rng.minmax -> [obj, obj] + * rng.minmax {| a,b | block } -> [obj, obj] + * + * Returns a two element array which contains the minimum and the + * maximum value in the range. + * + * Can be given an optional block to override the default comparison + * method <code>a <=> b</code>. + */ + +static VALUE +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)); +} + int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp) { @@ -1697,6 +1718,7 @@ Init_Range(void) rb_define_method(rb_cRange, "last", range_last, -1); rb_define_method(rb_cRange, "min", range_min, -1); rb_define_method(rb_cRange, "max", range_max, -1); + rb_define_method(rb_cRange, "minmax", range_minmax, 0); rb_define_method(rb_cRange, "size", range_size, 0); rb_define_method(rb_cRange, "to_a", range_to_a, 0); rb_define_method(rb_cRange, "entries", range_to_a, 0); diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index 14fd136aa6..699e4459be 100644 --- a/test/ruby/test_range.rb +++ b/test/ruby/test_range.rb @@ -121,6 +121,27 @@ class TestRange < Test::Unit::TestCase assert_raise(RangeError) { (1...).max(3) } end + def test_minmax + assert_equal([1, 2], (1..2).minmax) + assert_equal([nil, nil], (2..1).minmax) + assert_equal([1, 1], (1...2).minmax) + assert_raise(RangeError) { (1..).minmax } + assert_raise(RangeError) { (1...).minmax } + + assert_equal([1.0, 2.0], (1.0..2.0).minmax) + assert_equal([nil, nil], (2.0..1.0).minmax) + assert_raise(TypeError) { (1.0...2.0).minmax } + assert_raise(TypeError) { (1...1.5).minmax } + assert_raise(TypeError) { (1.5...2).minmax } + + assert_equal([-0x80000002, -0x80000002], ((-0x80000002)...(-0x80000001)).minmax) + + assert_equal([0, 0], (0..0).minmax) + assert_equal([nil, nil], (0...0).minmax) + + assert_equal([2, 1], (1..2).minmax{|a, b| b <=> a}) + end + def test_initialize_twice r = eval("1..2") assert_raise(NameError) { r.instance_eval { initialize 3, 4 } } |