[#30743] 大きな数の大まかな割り算 — Yukihiro Matsumoto <matz@...>

まつもと ゆきひろです

17 messages 2007/05/01

[#30827] Supporting Fiber — SASADA Koichi <ko1@...>

 ささだです。

22 messages 2007/05/27

[ruby-dev:30792] minor improvements and doc fix for Enumerable

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-05-18 17:17:14 UTC
List: ruby-dev #30792
なかだです。

injectは、NODEを使うよりもローカル変数を直接使うほうがちょっと
速いような気がします。

oneは、一度falseになってしまえばそれ以上続行する必要はないんじゃ
ないでしょうか。ドキュメントの例は、その前の記述とも実際の動作と
もあっていないものがあります。


Index: enum.c
===================================================================
--- enum.c	(revision 12297)
+++ enum.c	(working copy)
@@ -336,12 +336,12 @@ enum_to_a(VALUE obj)
 
 static VALUE
-inject_i(VALUE i, VALUE memo)
+inject_i(VALUE i, VALUE p)
 {
-    if (RARRAY_PTR(memo)[0] == Qundef) {
-        RARRAY_PTR(memo)[0] = i;
+    VALUE *memo = (VALUE *)p;
+    if (memo[0] == Qundef) {
+	memo[0] = i;
     }
     else {
-	RARRAY_PTR(memo)[1] = i;
-        RARRAY_PTR(memo)[0] = rb_yield(memo);
+	memo[0] = rb_yield_values(2, memo[0], i);
     }
     return Qnil;
@@ -349,15 +349,13 @@ inject_i(VALUE i, VALUE memo)
 
 static VALUE
-inject_op_i(VALUE i, NODE *node)
+inject_op_i(VALUE i, VALUE p)
 {
-    VALUE memo = node->nd_rval;
+    VALUE *memo = (VALUE *)p;
 
-    if (RARRAY_PTR(memo)[0] == Qundef) {
-        RARRAY_PTR(memo)[0] = i;
+    if (memo[0] == Qundef) {
+	memo[0] = i;
     }
     else {
-	VALUE v = RARRAY_PTR(memo)[0];
-	RARRAY_PTR(memo)[1] = i;
-        RARRAY_PTR(memo)[0] = rb_funcall(v, node->nd_vid, 1, i);
+	memo[0] = rb_funcall(memo[0], (ID)memo[1], 1, i);
     }
     return Qnil;
@@ -429,22 +427,18 @@ static VALUE
 enum_inject(int argc, VALUE *argv, VALUE obj)
 {
-    VALUE memo, a1, a2, tmp;
-    NODE *node = 0;
+    VALUE memo[2];
+    VALUE (*iter)(VALUE, VALUE) = inject_i;
 
-    switch (rb_scan_args(argc, argv, "02", &a1, &a2)) {
+    switch (rb_scan_args(argc, argv, "02", &memo[0], &memo[1])) {
       case 0:
-	memo = rb_ary_new3(2, Qundef, Qnil);
-	rb_block_call(obj, id_each, 0, 0, inject_i, memo);
+	memo[0] = Qundef;
 	break;
       case 1:
 	if (rb_block_given_p()) {
-	    memo = rb_ary_new3(2, a1, Qnil);
-	    rb_block_call(obj, id_each, 0, 0, inject_i, memo);
-	}
-	else {
-	    memo = rb_ary_new3(2, Qundef, Qnil);
-	    node = rb_node_newnode(NODE_MEMO, rb_to_id(a1), memo, 0);
-	    rb_block_call(obj, id_each, 0, 0, inject_op_i, (VALUE)node);
+	    break;
 	}
+	memo[1] = (VALUE)rb_to_id(memo[0]);
+	memo[0] = Qundef;
+	iter = inject_op_i;
 	break;
       case 2:
@@ -452,12 +446,11 @@ enum_inject(int argc, VALUE *argv, VALUE
 	    rb_warning("given block not used");
 	}
-	memo = rb_ary_new3(2, a2, Qnil);
-	node = rb_node_newnode(NODE_MEMO, rb_to_id(a1), memo, 0);
-	rb_block_call(obj, id_each, 0, 0, inject_op_i, (VALUE)node);
+	memo[1] = (VALUE)rb_to_id(memo[1]);
+	iter = inject_op_i;
 	break;
     }
-    tmp = RARRAY_PTR(memo)[0];
-    if (tmp == Qundef) return Qnil;
-    return tmp;
+    rb_block_call(obj, id_each, 0, 0, iter, (VALUE)memo);
+    if (memo[0] == Qundef) return Qnil;
+    return memo[0];
 }
 
@@ -831,7 +824,7 @@ enum_any(VALUE obj)
 
 static VALUE
-one_iter_i(VALUE i, VALUE *memo)
+one_i(VALUE i, VALUE *memo)
 {
-    if (RTEST(rb_yield(i))) {
+    if (RTEST(i)) {
 	if (*memo == Qundef) {
 	    *memo = Qtrue;
@@ -839,4 +832,5 @@ one_iter_i(VALUE i, VALUE *memo)
 	else if (*memo == Qtrue) {
 	    *memo = Qfalse;
+	    rb_iter_break();
 	}
     }
@@ -845,15 +839,7 @@ one_iter_i(VALUE i, VALUE *memo)
 
 static VALUE
-one_i(VALUE i, VALUE *memo)
+one_iter_i(VALUE i, VALUE *memo)
 {
-    if (RTEST(i)) {
-	if (*memo == Qundef) {
-	    *memo = Qtrue;
-	}
-	else if (*memo == Qtrue) {
-	    *memo = Qfalse;
-	}
-    }
-    return Qnil;
+    return one_i(rb_yield(i), memo);
 }
 
@@ -870,5 +856,6 @@ one_i(VALUE i, VALUE *memo)
  *     %w{ant bear cat}.one? {|word| word.length == 4}   #=> true
  *     %w{ant bear cat}.one? {|word| word.length >= 4}   #=> false
- *     [ nil, true, 99 ].one?                            #=> true
+ *     [ nil, true, 99 ].one?                            #=> false
+ *     [ nil, true, false ].one?                         #=> true
  *     
  */
@@ -885,7 +872,7 @@ enum_one(VALUE obj)
 
 static VALUE
-none_iter_i(VALUE i, VALUE *memo)
+none_i(VALUE i, VALUE *memo)
 {
-    if (RTEST(rb_yield(i))) {
+    if (RTEST(i)) {
 	*memo = Qfalse;
 	rb_iter_break();
@@ -895,11 +882,7 @@ none_iter_i(VALUE i, VALUE *memo)
 
 static VALUE
-none_i(VALUE i, VALUE *memo)
+none_iter_i(VALUE i, VALUE *memo)
 {
-    if (RTEST(i)) {
-	*memo = Qfalse;
-	rb_iter_break();
-    }
-    return Qnil;
+    return none_i(rb_yield(i), memo);
 }
 


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread

Prev Next