[#7968] array .{first, last, at} — Kazunori NISHI <kazunori@...>

西@九大です。

25 messages 1999/10/07
[#7969] Re: array .{first, last, at} — nobu.nakada@... 1999/10/07

なかだです。

[#7983] Re: array .{first, last, at} — Kazunori NISHI <kazunori@...> 1999/10/12

西@九大です。

[#7984] Re: array .{first, last, at} — matz@... (Yukihiro Matsumoto) 1999/10/12

まつもと ゆきひろです

[#7985] [patch] Array#delete_at w/ minus value — EGUCHI Osamu <eguchi@...> 1999/10/12

えぐち@エスアンドイーです。

[ruby-dev:8015] [patch] Array modify check (Re: [patch] Array#delete_at w/ minus value)

From: EGUCHI Osamu <eguchi@...>
Date: 1999-10-13 15:53:18 UTC
List: ruby-dev #8015
えぐち@エスアンドイー です。

>>> In message [ruby-dev:7985] [patch] Array#delete_at w/ minus value
    On Tue, 12 Oct 1999 13:00:39 +0900, EGUCHI Osamu <eguchi@cagiva.shizuokanet.ne.jp> said:

eguchi> えぐち@エスアンドイーです。
eguchi> 
eguchi> 負のインデックスを Array の delete_at の引数に
eguchi> 使えるようにしてみました。

rb_ary_delete_at() の rb_ary_modify() の位置がまずかったです。
これだと、(インデクスが範囲外が理由の)変更未遂を
見逃してしまいます。

  frozen, sort 中の lock それに taint は、
  *変更を行わない場合* も検査すべきと解釈しました。
	...合ってますか?

そういう目で見ると、

 * Array#sort! で length <= 1 の時にも検査必要?

 * Array#concat にも ?

 ? Array#clear には ???

あと、

 * Array#sort が length == 0 の場合に限り、
   dup した新しい配列を返さないで self を返している。

 * 再帰の抑止、 rb_ary_plus() と rb_ary_concat()

というのに気がつきました。

#
いま Ruby で、ある種のアセンブラのオプティマイザ書いてますが、
Ruby の配列って欲しい機能が完備してるので、サクサク作れて快適☆
そのおかげで、このオプティマイザは Ruby の配列クラスの
テストプログラムと化してます(笑)。

	えぐち

Index: array.c
===================================================================
RCS file: /usr/home/eguchi/cvs.netlab.co.jp//ruby/array.c,v
retrieving revision 1.3
diff -d -u -r1.3 array.c
--- array.c	1999/10/13 06:44:40	1.3
+++ array.c	1999/10/13 15:29:50
@@ -914,9 +914,9 @@
 rb_ary_sort_bang(ary)
     VALUE ary;
 {
+    rb_ary_modify(ary);
     if (RARRAY(ary)->len <= 1) return ary;
 
-    rb_ary_modify(ary);
     FL_SET(ary, ARY_TMPLOCK);	/* prohibit modification during sort */
     rb_ensure(sort_internal, ary, sort_unlock, ary);
     return ary;
@@ -926,8 +926,9 @@
 rb_ary_sort(ary)
     VALUE ary;
 {
+    ary = rb_ary_dup(ary);
     if (RARRAY(ary)->len == 0) return ary;
-    return rb_ary_sort_bang(rb_ary_dup(ary));
+    return rb_ary_sort_bang(ary);
 }
 
 VALUE
@@ -966,11 +967,11 @@
     long i, pos = NUM2LONG(at), len = RARRAY(ary)->len;
     VALUE del = Qnil;
 
+    rb_ary_modify(ary);
     if (pos >= len) return Qnil;
     if (pos < 0) pos += len;
     if (pos < 0) return Qnil;
 
-    rb_ary_modify(ary);
     del = RARRAY(ary)->ptr[pos];
     for (i = pos + 1; i < len; i++, pos++) {
 	RARRAY(ary)->ptr[pos] = RARRAY(ary)->ptr[i];
@@ -1090,7 +1091,7 @@
     VALUE z;
 
     if (TYPE(y) != T_ARRAY) {
-	return rb_ary_plus(x, rb_Array(y));
+	y = rb_Array(y);
     }
 
     z = rb_ary_new2(RARRAY(x)->len + RARRAY(y)->len);
@@ -1106,8 +1107,9 @@
 {
     VALUE *p, *pend;
 
+    rb_ary_modify(x);
     if (TYPE(y) != T_ARRAY) {
-	return rb_ary_concat(x, rb_Array(y));
+	y = rb_Array(y);
     }
 
     p = RARRAY(y)->ptr;

In This Thread