トップ «前の日記(2005-01-23 (Sun)) 最新 次の日記(2005-01-28 (Fri))» 編集   RSS 1.0 FEED  

Journal InTime


2005-01-24 (Mon) [長年日記]

_ 087 複数の配列を並行処理する

今日はRuby講習会の講師。講習中にレシピブックの説明をしていて、

配列が非常に大きく、zipメソッドで配列を作る余地がない時は、Array#each_indexで繰り返します。

[Rubyレシピブック 268の技 p.150より引用]

という記述にはじめて気付いた。

よく読むと、レシピブックではArray#zipの戻り値に対してeachの 呼び出しを行っていて、

as.zip(bs) do |a, b|
  ...
end

のようにArray#zip自体にブロックを与える方法は 説明されていない。 もしかして、1.8.0とかの古いバージョンではブロックを渡せなかった のかなと思って、1.8.0のソースを見てみたが、

if (rb_block_given_p()) {
    for (i=0; i<RARRAY(ary)->len; i++) {
        VALUE tmp = rb_ary_new2(argc+1);

        rb_ary_push(tmp, rb_ary_entry(ary, i));
        for (j=0; j<argc; j++) {
            rb_ary_push(tmp, rb_ary_entry(argv[j], i));
        }
        rb_yield(tmp);
    }
    return Qnil;
}

のようになっていて、問題なさそうに見える。 cvs logで調べると、

revision 1.98
date: 2002/11/19 08:07:48;  author: matz;  state: Exp;  lines: +44 -3
* array.c (rb_ary_zip): iterates over items in the receiver.
  zipped with nil if argument arrays are shorter.  if arrays are
  longer, left items are ignored.  now works with blocks

この変更らしいので、レシピブックの記述はそれよりも前に書かれたのかな?

Tags: Ruby