[#26156] ruby 1.8.3 preview1 — Yukihiro Matsumoto <matz@...>

Hi,

28 messages 2005/05/12

[#26186] ruby_setenv dumps core with mod_ruby/1.4.2 — Tietew <tietew-ml-ruby-dev@...>

Tietew です。

15 messages 2005/05/18
[#26285] Re: ruby_setenv dumps core with mod_ruby/1.4.2 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/06/05

山本です。

[#26325] Re: ruby_setenv dumps core with mod_ruby/1.4.2 — Tietew <tietew-ml-ruby-dev@...> 2005/06/10

Tietew です。

[#26187] IO.select dumps core — Tanaka Akira <akr@...17n.org>

[ruby-talk:142505] で可能性に気がついたのですが、いま実験してみたとこ

31 messages 2005/05/18
[#26255] Re: IO.select dumps core — nobu@... 2005/05/31

なかだです。

[#26256] Re: IO.select dumps core — Tanaka Akira <akr@...17n.org> 2005/06/01

In article <200505311523.j4VFN4Y4005876@sharui.nakada.niregi.kanuma.tochigi.jp>,

[#26257] Re: IO.select dumps core — nobu@... 2005/06/01

なかだです。

[#26262] Re: IO.select dumps core — Tanaka Akira <akr@...17n.org> 2005/06/01

In article <200506010140.j511edY4012889@sharui.nakada.niregi.kanuma.tochigi.jp>,

[#26265] Re: IO.select dumps core — Takahiro Kambe <taca@...> 2005/06/02

In message <87u0khj377.fsf@m17n.org>

[#26365] Re: IO.select dumps core — とみたまさひろ <tommy@...> 2005/06/22

とみたです。

[#26366] Re: IO.select dumps core — nobu@... 2005/06/22

なかだです。

[#26369] Re: IO.select dumps core — とみたまさひろ <tommy@...> 2005/06/23

とみたです。

[#26242] many errors with soap/wsdl test on mswin32 — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

12 messages 2005/05/27
[#26249] Re: many errors with soap/wsdl test on mswin32 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2005/05/31

山本です。

[ruby-dev:26245] Enumerable#{min_by,max_by} and etc.

From: nobuyoshi nakada <nobuyoshi.nakada@...>
Date: 2005-05-27 12:04:25 UTC
List: ruby-dev #26245
なかだです。

http://yowaken.dip.jp/tdiary/20050527.html#p02 のEnumerable#min_by,
Enumerable#max_byが空のときにfalseを返すのとブロックがなくてもエラーに
ならない、という動作を修正するパッチです。今のところデータを持ちまわる
のにNODEを使っていますが、これはVALUEやVALUE[]を直接使っても充分じゃな
いかという気がします。

また、内部で呼出すメソッドも見せなくてもいいのではないかと。


* enum.c (enum_min_by, enum_max_by): return nil if no iteration.

* eval.c (rb_need_block): ensure a block is given.

* eval.c (backtrace): skip successive frames sharing same node.


Index: enum.c
===================================================================
RCS file: /cvs/ruby/src/ruby/enum.c,v
retrieving revision 1.54
diff -U2 -p -r1.54 enum.c
--- enum.c	30 Oct 2004 06:56:17 -0000	1.54
+++ enum.c	27 May 2005 10:21:56 -0000
@@ -81,9 +81,8 @@ static VALUE
 find_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     if (RTEST(rb_yield(i))) {
-	memo->u2.value = Qtrue;
-	memo->u1.value = i;
+	*memo = i;
 	rb_iter_break();
     }
@@ -112,11 +111,11 @@ enum_find(argc, argv, obj)
     VALUE obj;
 {
-    NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, Qfalse, 0);
+    VALUE memo = Qundef;
     VALUE if_none;
 
     rb_scan_args(argc, argv, "01", &if_none);
-    rb_iterate(rb_each, obj, find_i, (VALUE)memo);
-    if (memo->u2.value) {
-	return memo->u1.value;
+    rb_iterate(rb_each, obj, find_i, (VALUE)&memo);
+    if (memo != Qundef) {
+	return memo;
     }
     if (!NIL_P(if_none)) {
@@ -258,12 +257,11 @@ static VALUE
 inject_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
-    if (memo->u2.value) {
-        memo->u2.value = Qfalse;
-        memo->u1.value = i;
+    if (*memo == Qundef) {
+        *memo = i;
     }
     else {
-        memo->u1.value = rb_yield_values(2, memo->u1.value, i);
+        *memo = rb_yield_values(2, *memo, i);
     }
     return Qnil;
@@ -306,16 +304,9 @@ enum_inject(argc, argv, obj)
     VALUE *argv, obj;
 {
-    NODE *memo;
-    VALUE n;
+    VALUE memo = Qundef;
 
-    if (rb_scan_args(argc, argv, "01", &n) == 1) {
-        memo = rb_node_newnode(NODE_MEMO, n, Qfalse, 0);
-    }
-    else {
-        memo = rb_node_newnode(NODE_MEMO, Qnil, Qtrue, 0);
-    }
-    rb_iterate(rb_each, obj, inject_i, (VALUE)memo);
-    n = memo->u1.value;
-    return n;
+    rb_scan_args(argc, argv, "01", &memo);
+    rb_iterate(rb_each, obj, inject_i, (VALUE)&memo);
+    return memo;
 }
 
@@ -508,8 +499,8 @@ static VALUE
 all_iter_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     if (!RTEST(rb_yield(i))) {
-	memo->u1.value = Qfalse;
+	*memo = Qfalse;
 	rb_iter_break();
     }
@@ -520,8 +511,8 @@ static VALUE
 all_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     if (!RTEST(i)) {
-	memo->u1.value = Qfalse;
+	*memo = Qfalse;
 	rb_iter_break();
     }
@@ -550,10 +541,7 @@ enum_all(obj)
     VALUE obj;
 {
-    VALUE result;
-    NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, 0, 0);
+    VALUE result = Qtrue;
 
-    memo->u1.value = Qtrue;
-    rb_iterate(rb_each, obj, rb_block_given_p() ? all_iter_i : all_i, (VALUE)memo);
-    result = memo->u1.value;
+    rb_iterate(rb_each, obj, rb_block_given_p() ? all_iter_i : all_i, (VALUE)&result);
     return result;
 }
@@ -562,8 +550,8 @@ static VALUE
 any_iter_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     if (RTEST(rb_yield(i))) {
-	memo->u1.value = Qtrue;
+	*memo = Qtrue;
 	rb_iter_break();
     }
@@ -574,8 +562,8 @@ static VALUE
 any_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     if (RTEST(i)) {
-	memo->u1.value = Qtrue;
+	*memo = Qtrue;
 	rb_iter_break();
     }
@@ -605,10 +593,7 @@ enum_any(obj)
     VALUE obj;
 {
-    VALUE result;
-    NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, 0, 0);
+    VALUE result = Qfalse;
 
-    memo->u1.value = Qfalse;
-    rb_iterate(rb_each, obj, rb_block_given_p() ? any_iter_i : any_i, (VALUE)memo);
-    result = memo->u1.value;
+    rb_iterate(rb_each, obj, rb_block_given_p() ? any_iter_i : any_i, (VALUE)&result);
     return result;
 }
@@ -617,15 +602,15 @@ static VALUE
 min_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     VALUE cmp;
 
-    if (NIL_P(memo->u1.value)) {
-	memo->u1.value = i;
+    if (NIL_P(*memo)) {
+	*memo = i;
     }
     else {
-	cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
-	if (rb_cmpint(cmp, i, memo->u1.value) < 0) {
-	    memo->u1.value = i;
+	cmp = rb_funcall(i, id_cmp, 1, *memo);
+	if (rb_cmpint(cmp, i, *memo) < 0) {
+	    *memo = i;
 	}
     }
@@ -636,15 +621,15 @@ static VALUE
 min_ii(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     VALUE cmp;
 
-    if (NIL_P(memo->u1.value)) {
-	memo->u1.value = i;
+    if (NIL_P(*memo)) {
+	*memo = i;
     }
     else {
-	cmp = rb_yield_values(2, i, memo->u1.value);
-	if (rb_cmpint(cmp, i, memo->u1.value) < 0) {
-	    memo->u1.value = i;
+	cmp = rb_yield_values(2, i, *memo);
+	if (rb_cmpint(cmp, i, *memo) < 0) {
+	    *memo = i;
 	}
     }
@@ -671,9 +656,7 @@ enum_min(obj)
     VALUE obj;
 {
-    VALUE result;
-    NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, 0, 0);
+    VALUE result = Qnil;
 
-    rb_iterate(rb_each, obj, rb_block_given_p() ? min_ii : min_i, (VALUE)memo);
-    result = memo->u1.value;
+    rb_iterate(rb_each, obj, rb_block_given_p() ? min_ii : min_i, (VALUE)&result);
     return result;
 }
@@ -682,15 +665,15 @@ static VALUE
 max_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     VALUE cmp;
 
-    if (NIL_P(memo->u1.value)) {
-	memo->u1.value = i;
+    if (NIL_P(*memo)) {
+	*memo = i;
     }
     else {
-	cmp = rb_funcall(i, id_cmp, 1, memo->u1.value);
-	if (rb_cmpint(cmp, i, memo->u1.value) > 0) {
-	    memo->u1.value = i;
+	cmp = rb_funcall(i, id_cmp, 1, *memo);
+	if (rb_cmpint(cmp, i, *memo) > 0) {
+	    *memo = i;
 	}
     }
@@ -701,15 +684,15 @@ static VALUE
 max_ii(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     VALUE cmp;
 
-    if (NIL_P(memo->u1.value)) {
-	memo->u1.value = i;
+    if (NIL_P(*memo)) {
+	*memo = i;
     }
     else {
-	cmp = rb_yield_values(2, i, memo->u1.value);
-	if (rb_cmpint(cmp, i, memo->u1.value) > 0) {
-	    memo->u1.value = i;
+	cmp = rb_yield_values(2, i, *memo);
+	if (rb_cmpint(cmp, i, *memo) > 0) {
+	    *memo = i;
 	}
     }
@@ -735,9 +718,7 @@ enum_max(obj)
     VALUE obj;
 {
-    VALUE result;
-    NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, 0, 0);
+    VALUE result = Qnil;
 
-    rb_iterate(rb_each, obj, rb_block_given_p() ? max_ii : max_i, (VALUE)memo);
-    result = memo->u1.value;
+    rb_iterate(rb_each, obj, rb_block_given_p() ? max_ii : max_i, (VALUE)&result);
     return result;
 }
@@ -746,16 +727,16 @@ static VALUE
 min_by_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     VALUE v;
 
     v = rb_yield(i);
-    if (NIL_P(memo->u1.value)) {
-	memo->u1.value = v;
-	memo->u2.value = i;
-    }
-    else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo->u1.value), v, memo->u1.value) < 0) {
-	memo->u1.value = v;
-	memo->u2.value = i;
+    if (NIL_P(memo[0])) {
+	memo[0] = v;
+	memo[1] = i;
+    }
+    else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo[0]), v, memo[0]) < 0) {
+	memo[0] = v;
+	memo[1] = i;
     }
     return Qnil;
@@ -777,10 +758,10 @@ enum_min_by(obj)
     VALUE obj;
 {
-    VALUE result;
-    NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, 0, 0);
+    VALUE memo[2];
 
+    rb_need_block();
+    memo[0] = memo[1] = Qnil;
     rb_iterate(rb_each, obj, min_by_i, (VALUE)memo);
-    result = memo->u2.value;
-    return result;
+    return memo[1];
 }
 
@@ -788,16 +769,16 @@ static VALUE
 max_by_i(i, memo)
     VALUE i;
-    NODE *memo;
+    VALUE *memo;
 {
     VALUE v;
 
     v = rb_yield(i);
-    if (NIL_P(memo->u1.value)) {
-	memo->u1.value = v;
-	memo->u2.value = i;
-    }
-    else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo->u1.value), v, memo->u1.value) > 0) {
-	memo->u1.value = v;
-	memo->u2.value = i;
+    if (NIL_P(memo[0])) {
+	memo[0] = v;
+	memo[1] = i;
+    }
+    else if (rb_cmpint(rb_funcall(v, id_cmp, 1, memo[0]), v, memo[0]) > 0) {
+	memo[0] = v;
+	memo[1] = i;
     }
     return Qnil;
@@ -819,10 +800,10 @@ enum_max_by(obj)
     VALUE obj;
 {
-    VALUE result;
-    NODE *memo = rb_node_newnode(NODE_MEMO, Qnil, 0, 0);
+    VALUE memo[2];
 
+    rb_need_block();
+    memo[0] = memo[1] = Qnil;
     rb_iterate(rb_each, obj, max_by_i, (VALUE)memo);
-    result = memo->u2.value;
-    return result;
+    return memo[1];
 }
 
@@ -830,8 +811,8 @@ static VALUE
 member_i(item, memo)
     VALUE item;
-    NODE *memo;
+    VALUE *memo;
 {
-    if (rb_equal(item, memo->u1.value)) {
-	memo->u2.value = Qtrue;
+    if (rb_equal(item, memo[0])) {
+	memo[1] = Qtrue;
 	rb_iter_break();
     }
@@ -856,10 +837,10 @@ enum_member(obj, val)
     VALUE obj, val;
 {
-    VALUE result;
-    NODE *memo = rb_node_newnode(NODE_MEMO, val, Qfalse, 0);
+    VALUE memo[2];
 
+    memo[0] = val;
+    memo[1] = Qfalse;
     rb_iterate(rb_each, obj, member_i, (VALUE)memo);
-    result = memo->u2.value;
-    return result;
+    return memo[1];
 }
 
@@ -867,8 +848,8 @@ static VALUE
 each_with_index_i(val, memo)
     VALUE val;
-    NODE *memo;
+    VALUE *memo;
 {
-    rb_yield_values(2, val, INT2FIX(memo->u3.cnt));
-    memo->u3.cnt++;
+    rb_yield_values(2, val, INT2FIX(*memo));
+    ++*memo;
     return Qnil;
 }
@@ -893,7 +874,8 @@ enum_each_with_index(obj)
     VALUE obj;
 {
-    NODE *memo = rb_node_newnode(NODE_MEMO, 0, 0, 0);
+    VALUE memo = 0;
 
-    rb_iterate(rb_each, obj, each_with_index_i, (VALUE)memo);
+    rb_need_block();
+    rb_iterate(rb_each, obj, each_with_index_i, (VALUE)&memo);
     return obj;
 }
@@ -902,9 +884,9 @@ static VALUE
 zip_i(val, memo)
     VALUE val;
-    NODE *memo;
+    VALUE *memo;
 {
-    VALUE result = memo->u1.value;
-    VALUE args = memo->u2.value;
-    int idx = memo->u3.cnt++;
+    VALUE result = memo[0];
+    VALUE args = memo[1];
+    int idx = memo[2]++;
     VALUE tmp;
     int i;
@@ -955,5 +937,5 @@ enum_zip(argc, argv, obj)
     int i;
     VALUE result;
-    NODE *memo;
+    VALUE memo[3];
 
     for (i=0; i<argc; i++) {
@@ -961,5 +943,7 @@ enum_zip(argc, argv, obj)
     }
     result = rb_block_given_p() ? Qnil : rb_ary_new();
-    memo = rb_node_newnode(NODE_MEMO, result, rb_ary_new4(argc, argv), 0);
+    memo[0] = result;
+    memo[1] = rb_ary_new4(argc, argv);
+    memo[2] = 0;
     rb_iterate(rb_each, obj, zip_i, (VALUE)memo);
 
Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.783
diff -U2 -p -r1.783 eval.c
--- eval.c	25 May 2005 23:33:10 -0000	1.783
+++ eval.c	27 May 2005 09:57:39 -0000
@@ -4716,4 +4716,12 @@ static VALUE bmcall _((VALUE, VALUE));
 static int method_arity _((VALUE));
 
+void
+rb_need_block()
+{
+    if (!rb_block_given_p()) {
+	localjump_error("no block given", Qnil, 0);
+    }
+}
+
 static VALUE
 rb_yield_0(val, self, klass, flags, avalue)
@@ -4733,7 +4741,5 @@ rb_yield_0(val, self, klass, flags, aval
     int state;
 
-    if (!rb_block_given_p()) {
-	localjump_error("no block given", Qnil, 0);
-    }
+    rb_need_block();
 
     PUSH_VARS();
@@ -6075,6 +6081,7 @@ backtrace(lev)
 	}
     }
-    while (frame && (n = frame->node)) {
+    for (; frame && (n = frame->node); frame = frame->prev) {
 	if (frame->prev && frame->prev->this_func) {
+	    if (frame->prev->node == n) continue;
 	    snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
 		     n->nd_file, nd_line(n),
@@ -6085,5 +6092,4 @@ backtrace(lev)
 	}
 	rb_ary_push(ary, rb_str_new2(buf));
-	frame = frame->prev;
     }
 
Index: ruby.h
===================================================================
RCS file: /cvs/ruby/src/ruby/ruby.h,v
retrieving revision 1.113
diff -U2 -p -r1.113 ruby.h
--- ruby.h	15 May 2005 09:56:49 -0000	1.113
+++ ruby.h	27 May 2005 10:03:12 -0000
@@ -552,4 +552,5 @@ VALUE rb_yield_values __((int n, ...));
 VALUE rb_yield_splat _((VALUE));
 int rb_block_given_p _((void));
+void rb_need_block _((void));
 VALUE rb_iterate _((VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE));
 VALUE rb_rescue _((VALUE(*)(ANYARGS),VALUE,VALUE(*)(ANYARGS),VALUE));


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

In This Thread

Prev Next