diff options
author | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-05-29 19:18:54 +0000 |
---|---|---|
committer | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-05-29 19:18:54 +0000 |
commit | 3a3e250975d0ce34b0e5628a2fc2a3bfa7722188 (patch) | |
tree | a9f5cc6aa90562d1449295970feae2c07ec9eef8 /enum.c | |
parent | cd5eb03b58f270cd1200a9914103a0b6a19b9397 (diff) | |
download | ruby-3a3e250975d0ce34b0e5628a2fc2a3bfa7722188.tar.gz |
* enum.c (enum_count, count_all_i, Init_Enumerable),
array.c (rb_ary_count): If no argument or block is given, count
the number of all elements.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'enum.c')
-rw-r--r-- | enum.c | 32 |
1 files changed, 27 insertions, 5 deletions
@@ -14,7 +14,7 @@ #include "ruby/util.h" VALUE rb_mEnumerable; -static ID id_each, id_eqq, id_cmp, id_next; +static ID id_each, id_eqq, id_cmp, id_next, id_size; static VALUE enum_values_pack(int argc, VALUE *argv) @@ -108,15 +108,29 @@ count_iter_i(VALUE i, VALUE memop, int argc, VALUE *argv) return Qnil; } +static VALUE +count_all_i(VALUE i, VALUE memop, int argc, VALUE *argv) +{ + VALUE *memo = (VALUE*)memop; + + memo[0]++; + return Qnil; +} + /* * call-seq: + * enum.count => int * enum.count(item) => int * enum.count {| obj | block } => int * - * Returns the number of items in <i>enum</i> for which equals to <i>item</i>. - * If a block is given, counts the number of elements yielding a true value. + * Returns the number of items in <i>enum</i>, where #size is called + * if it responds to it, otherwise the items are counted through + * enumeration. If an argument is given, counts the number of items + * in <i>enum</i>, for which equals to <i>item</i>. If a block is + * given, counts the number of elements yielding a true value. * * ary = [1, 2, 4, 2] + * ary.count # => 4 * ary.count(2) # => 2 * ary.count{|x|x%2==0} # => 3 * @@ -129,8 +143,15 @@ enum_count(int argc, VALUE *argv, VALUE obj) rb_block_call_func *func; if (argc == 0) { - RETURN_ENUMERATOR(obj, 0, 0); - func = count_iter_i; + if (rb_block_given_p()) { + func = count_iter_i; + } + else { + if (rb_respond_to(obj, id_size)) { + return rb_funcall(obj, id_size, 0, 0); + } + func = count_all_i; + } } else { rb_scan_args(argc, argv, "1", &memo[1]); @@ -1826,5 +1847,6 @@ Init_Enumerable(void) id_each = rb_intern("each"); id_cmp = rb_intern("<=>"); id_next = rb_intern("next"); + id_size = rb_intern("size"); } |