[ruby-dev:24268] Re: Array#collect! dumps core

From: nobu@...
Date: 2004-09-15 03:01:58 UTC
List: ruby-dev #24268
なかだです。

At Tue, 14 Sep 2004 18:32:01 +0900,
Tanaka Akira wrote in [ruby-dev:24264]:
> > yieldした結果にしたがって書き換えるのは、reject!もありますね。
> 
> そうですね。ただ、len を書き換えるところに break するのは変だと思いま
> す。

確かに。しかし、ループの途中で短くなった場合、結果はどうなるべ
きなんでしょうねぇ。元の位置で切り捨てられた要素は、reject!後も
切り捨てられる、という仕様も考えられなくはないんですが、全要素
の対応を覚えておかなきゃならないというのもめんどうだし。

もう一点、ブロック自体は常に偽を返していても、中でarrayを変更し
た場合もreject!はarrayを返してますが、これはブロックが真を返し
た場合だけのほうがいいんじゃないでしょうか。

[ruby-dev:24262]への追加です。


diff -U2 array.c array.c
--- array.c	14 Sep 2004 04:55:03 -0000
+++ array.c	15 Sep 2004 02:54:46 -0000
@@ -2050,8 +2050,12 @@
 {
     long i1, i2;
+    VALUE result = Qnil;
 
     rb_ary_modify(ary);
     for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
-	if (RTEST(rb_yield(RARRAY(ary)->ptr[i1]))) continue;
+	if (RTEST(rb_yield(RARRAY(ary)->ptr[i1]))) {
+	    result = ary;
+	    continue;
+	}
 	if (i1 != i2) {
 	    if (i1 >= RARRAY(ary)->len) break;
@@ -2060,8 +2064,7 @@
 	i2++;
     }
-    if (RARRAY(ary)->len == i2) return Qnil;
-    RARRAY(ary)->len = i2;
+    if (i2 < RARRAY(ary)->len) RARRAY(ary)->len = i2;
 
-    return ary;
+    return result;
 }
 


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

In This Thread