なかだです。

At Thu, 30 Dec 1999 17:00:14 +0900,
gotoken / math.sci.hokudai.ac.jp (GOTO Kentaro) wrote:
> # 何回まわるのかなー(答:size/arity)と思った後で、どんだけ余
> # るのかなー(答:size%arity)と思ったらしい

  ありがち。(^^)

  思い付きですが、こういうのはどうでしょうか。ブロック側じゃなく
て呼び出し側で個数を指定するタイプ。負の値を与えられたときとか、
reverse_each とかについては全然考えてませんが。(^^; 

class Array
  def each(step = 1)
    step > 0 or
      raise ArgumentError, "negative or zero argument(#{step})"
    i = 0
    while i < size
      yield(*self[i, step])
      i += step
    end
  end
end

  いちいち配列を作り直さないように C で書き直せばこんな風。どっち
かというとごとけんさんのに近いような。

diff -ru2p dist/ChangeLog build/ChangeLog
--- dist/ChangeLog	Tue Dec 14 18:10:17 1999
+++ build/ChangeLog	Sat Jan  1 09:51:18 2000
@@ -1,2 +1,8 @@
+Sat Jan  1 09:50:28 2000  Nobuyoshi Nakada  <nobu.nakada / nifty.ne.jp>
+
+	* array.c (rb_ary_each_index): Array#each takes an optional
+	  argument which specifies how many elements would be passed to
+	  the block.
+
 Mon Dec 13 15:15:31 1999  Yukihiro Matsumoto  <matz / netlab.co.jp>
 
diff -ru2p dist/array.c build/array.c
--- dist/array.c	Tue Dec 14 18:10:17 1999
+++ build/array.c	Sat Jan  1 03:48:43 2000
@@ -577,11 +577,42 @@ rb_ary_aset(argc, argv, ary)
 
 VALUE
-rb_ary_each(ary)
+rb_ary_each(argc, argv, ary)
+    int argc;
+    VALUE *argv;
     VALUE ary;
 {
-    long i;
+    long i, n, step = 1;
+    VALUE tmp;
 
-    for (i=0; i<RARRAY(ary)->len; i++) {
-	rb_yield(RARRAY(ary)->ptr[i]);
+    if (rb_scan_args(argc, argv, "01", &tmp) == 1) {
+	step = NUM2LONG(tmp);
+	if (step <= 0)
+	    rb_raise(rb_eArgError, "negative or zero argument(%ld)", step);
+    }
+
+    if (step == 1) {
+	for (i = 0; i < RARRAY(ary)->len; i++) {
+	    rb_yield(RARRAY(ary)->ptr[i]);
+	}
+    } else if (step >= RARRAY(ary)->len) {
+	rb_yield(ary);
+    } else {
+	struct RArray arg;
+	OBJSETUP(&arg, rb_cArray, T_ARRAY);
+	arg.capa = step;
+	arg.len = step;
+	arg.ptr = 0;
+	for (i = 0, n = RARRAY(ary)->len / step; n > 0; --n, i += step) {
+	    arg.ptr = &RARRAY(ary)->ptr[i];
+	    rb_yield((VALUE)&arg);
+	}
+	n = RARRAY(ary)->len - i;
+	if (n > 0) {
+	    arg.len = n;
+	    arg.ptr = &RARRAY(ary)->ptr[i];
+	    rb_yield((VALUE)&arg);
+	}
+	arg.len = 0;
+	arg.ptr = 0;
     }
     return ary;
@@ -1500,5 +1531,5 @@ Init_Array()
     rb_define_method(rb_cArray, "shift", rb_ary_shift, 0);
     rb_define_method(rb_cArray, "unshift", rb_ary_unshift, 1);
-    rb_define_method(rb_cArray, "each", rb_ary_each, 0);
+    rb_define_method(rb_cArray, "each", rb_ary_each, -1);
     rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0);
     rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0);
diff -ru2p dist/intern.h build/intern.h
--- dist/intern.h	Tue Dec 14 18:10:21 1999
+++ build/intern.h	Sat Jan  1 03:53:32 2000
@@ -19,5 +19,5 @@ VALUE rb_ary_shift _((VALUE));
 VALUE rb_ary_unshift _((VALUE, VALUE));
 VALUE rb_ary_entry _((VALUE, long));
-VALUE rb_ary_each _((VALUE));
+VALUE rb_ary_each _((int, VALUE*, VALUE));
 VALUE rb_ary_join _((VALUE, VALUE));
 VALUE rb_ary_print_on _((VALUE, VALUE));

-- 
そうだ 強気に ちょっと インチキに☆彡
    中田 "Bugるくらいがちょうどいいかも;-)" 伸悦