[前][次][番号順一覧][スレッド一覧]

ruby-changes:50987

From: mame <ko1@a...>
Date: Fri, 20 Apr 2018 00:18:59 +0900 (JST)
Subject: [ruby-changes:50987] mame:r63194 (trunk): Make Range#min, max, include?, cover?, and === to support endless range

mame	2018-04-20 00:18:53 +0900 (Fri, 20 Apr 2018)

  New Revision: 63194

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63194

  Log:
    Make Range#min, max, include?, cover?, and === to support endless range

  Modified files:
    trunk/range.c
    trunk/test/ruby/test_range.rb
Index: range.c
===================================================================
--- range.c	(revision 63193)
+++ range.c	(revision 63194)
@@ -960,7 +960,7 @@ range_min(int argc, VALUE *argv, VALUE r https://github.com/ruby/ruby/blob/trunk/range.c#L960
 	struct cmp_opt_data cmp_opt = { 0, 0 };
 	VALUE b = RANGE_BEG(range);
 	VALUE e = RANGE_END(range);
-	int c = OPTIMIZED_CMP(b, e, cmp_opt);
+	int c = NIL_P(e) ? -1 : OPTIMIZED_CMP(b, e, cmp_opt);
 
 	if (c > 0 || (c == 0 && EXCL(range)))
 	    return Qnil;
@@ -991,6 +991,8 @@ range_max(int argc, VALUE *argv, VALUE r https://github.com/ruby/ruby/blob/trunk/range.c#L991
     VALUE e = RANGE_END(range);
     int nm = FIXNUM_P(e) || rb_obj_is_kind_of(e, rb_cNumeric);
 
+    if (NIL_P(e)) return Qnil;
+
     if (rb_block_given_p() || (EXCL(range) && !nm) || argc) {
         return rb_call_super(argc, argv);
     }
@@ -1200,9 +1202,17 @@ range_include(VALUE range, VALUE val) https://github.com/ruby/ruby/blob/trunk/range.c#L1202
 	!NIL_P(rb_check_to_integer(end, "to_int"))) {
 	return r_cover_p(range, beg, end, val);
     }
-    else if (RB_TYPE_P(beg, T_STRING) && RB_TYPE_P(end, T_STRING)) {
-	VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
-	return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
+    else if (RB_TYPE_P(beg, T_STRING)) {
+	if (RB_TYPE_P(end, T_STRING)) {
+	    VALUE rb_str_include_range_p(VALUE beg, VALUE end, VALUE val, VALUE exclusive);
+	    return rb_str_include_range_p(beg, end, val, RANGE_EXCL(range));
+	}
+	else if (NIL_P(end)) {
+	    VALUE r = rb_funcall(beg, id_cmp, 1, val);
+	    if (NIL_P(r)) return Qfalse;
+	    if (rb_cmpint(r, beg, val) <= 0) return Qtrue;
+	    return Qfalse;
+	}
     }
     /* TODO: ruby_frame->this_func = rb_intern("include?"); */
     return rb_call_super(1, &val);
@@ -1239,7 +1249,7 @@ r_cover_p(VALUE range, VALUE beg, VALUE https://github.com/ruby/ruby/blob/trunk/range.c#L1249
 {
     if (r_less(beg, val) <= 0) {
 	int excl = EXCL(range);
-	if (r_less(val, end) <= -excl)
+	if (NIL_P(end) || r_less(val, end) <= -excl)
 	    return Qtrue;
     }
     return Qfalse;
Index: test/ruby/test_range.rb
===================================================================
--- test/ruby/test_range.rb	(revision 63193)
+++ test/ruby/test_range.rb	(revision 63194)
@@ -79,22 +79,27 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L79
     assert_equal(1, (1..2).min)
     assert_equal(nil, (2..1).min)
     assert_equal(1, (1...2).min)
+    assert_equal(1, (1..).min)
 
     assert_equal(1.0, (1.0..2.0).min)
     assert_equal(nil, (2.0..1.0).min)
     assert_equal(1, (1.0...2.0).min)
+    assert_equal(1, (1.0..).min)
 
     assert_equal(0, (0..0).min)
     assert_equal(nil, (0...0).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))
   end
 
   def test_max
     assert_equal(2, (1..2).max)
     assert_equal(nil, (2..1).max)
     assert_equal(1, (1...2).max)
+    assert_equal(nil, (1..).max)
+    assert_equal(nil, (1...).max)
 
     assert_equal(2.0, (1.0..2.0).max)
     assert_equal(nil, (2.0..1.0).max)
@@ -109,6 +114,7 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L114
 
     assert_equal([10,9,8], (0..10).max(3))
     assert_equal([9,8,7], (0...10).max(3))
+    # XXX: How should (0...).max(3) behave?
   end
 
   def test_initialize_twice
@@ -360,6 +366,11 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L366
     assert_equal("a", ("a"..."c").first)
     assert_equal("c", ("a"..."c").last)
     assert_equal(0, (2...0).last)
+
+    assert_equal([0, 1, 2], (0..nil).first(3))
+    assert_equal(0, (0..nil).first)
+    assert_equal("a", ("a"..nil).first)
+    # XXX: How should (0...).last(3) behave?
   end
 
   def test_to_s
@@ -389,6 +400,8 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L400
   def test_eqq
     assert_operator(0..10, :===, 5)
     assert_not_operator(0..10, :===, 11)
+    assert_operator(5..nil, :===, 11)
+    assert_not_operator(5..nil, :===, 0)
   end
 
   def test_eqq_time
@@ -396,6 +409,8 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L409
     t = Time.now
     assert_nothing_raised(TypeError, bug11113) {
       assert_operator(t..(t+10), :===, t+5)
+      assert_operator(t.., :===, t+5)
+      assert_not_operator(t.., :===, t-5)
     }
   end
 
@@ -430,6 +445,8 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L445
     assert_not_include("a"..."z", "z")
     assert_not_include("a".."z", "cc")
     assert_include(0...10, 5)
+    assert_include(5..., 10)
+    assert_not_include(5..., 0)
   end
 
   def test_cover
@@ -438,6 +455,9 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L455
     assert_operator("a"..."z", :cover?, "y")
     assert_not_operator("a"..."z", :cover?, "z")
     assert_operator("a".."z", :cover?, "cc")
+    assert_not_operator(5..., :cover?, 0)
+    assert_not_operator(5..., :cover?, "a")
+    assert_operator(5.., :cover?, 10)
   end
 
   def test_beg_len
@@ -515,6 +535,11 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L535
     assert_equal 6, (1...6.3).size
     assert_equal 5, (1.1...6).size
     assert_equal 42, (1..42).each.size
+    assert_nil ("a"..."z").size
+
+    assert_nil (1...).size
+    assert_nil (1.0...).size
+    assert_nil ("a"...).size
   end
 
   def test_bsearch_typechecks_return_values

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]