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

ruby-changes:59064

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Wed, 4 Dec 2019 15:33:15 +0900 (JST)
Subject: [ruby-changes:59064] 00bbdf4451 (master): implement Range#count

https://git.ruby-lang.org/ruby.git/commit/?id=00bbdf4451

From 00bbdf4451d0e66f0f7823e77c47ac310614c1c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Wed, 4 Dec 2019 15:31:51 +0900
Subject: implement Range#count

As matz requested in [Bug #16366].

diff --git a/range.c b/range.c
index 07a0b40..f701c16 100644
--- a/range.c
+++ b/range.c
@@ -1596,6 +1596,42 @@ range_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/range.c#L1596
     return rb_struct_alloc_noinit(klass);
 }
 
+/*
+ *  call-seq:
+ *     range.count                 -> int
+ *     range.count(item)           -> int
+ *     range.count { |obj| block } -> int
+ *
+ *  Identical to Enumerable#count, except it returns Infinity for endless
+ *  ranges.
+ *
+ */
+static VALUE
+range_count(int argc, VALUE *argv, VALUE range)
+{
+    if (argc != 0) {
+        /* It is odd for instace (1...).count(0) to return Infinity. Just let
+         * it loop. */
+        return rb_call_super(argc, argv);
+    }
+    else if (rb_block_given_p()) {
+        /* Likewise it is odd for instace (1...).count {|x| x == 0 } to return
+         * Infinity. Just let it loop. */
+        return rb_call_super(argc, argv);
+    }
+    else if (NIL_P(RANGE_END(range))) {
+        /* We are confident that the answer is Infinity. */
+        return DBL2NUM(HUGE_VAL);
+    }
+    else if (NIL_P(RANGE_BEG(range))) {
+        /* We are confident that the answer is Infinity. */
+        return DBL2NUM(HUGE_VAL);
+    }
+    else {
+        return rb_call_super(argc, argv);
+    }
+}
+
 /*  A Range represents an interval---a set of values with a
  *  beginning and an end. Ranges may be constructed using the
  *  <em>s</em><code>..</code><em>e</em> and
@@ -1733,4 +1769,5 @@ Init_Range(void) https://github.com/ruby/ruby/blob/trunk/range.c#L1769
     rb_define_method(rb_cRange, "member?", range_include, 1);
     rb_define_method(rb_cRange, "include?", range_include, 1);
     rb_define_method(rb_cRange, "cover?", range_cover, 1);
+    rb_define_method(rb_cRange, "count", range_count, -1);
 }
diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb
index 4df1453..800cee9 100644
--- a/test/ruby/test_range.rb
+++ b/test/ruby/test_range.rb
@@ -950,4 +950,8 @@ class TestRange < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_range.rb#L950
   def test_beginless_range_iteration
     assert_raise(TypeError) { (..1).each { } }
   end
+
+  def test_count
+    assert_equal(Float::INFINITY, (1..).count)
+  end
 end
-- 
cgit v0.10.2


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

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