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/