Ruby的配列イテレータの実装 (prototype.js)

開発版 prototype.js を読んでみて、かなり勉強になる内容だったので、何点かメモしておきたいと思います。

まず、for ループで配列要素ごとに関数(クロージャ)呼び出しをするという、最も一般的な部分は、ひとつのメソッドとして独立させています。

引用するとこう:

  _each: function(iterator) {
    for (var i = 0; i < this.length; i++)
      iterator(this[i]);
  },

これはまぁ当然のことなんですが、そうすると、detect (find) なんかの場合に途中でループを抜けることができなくて困ります。このため、iterator の中でエラーを発生させて抜け出す仕組みになっております。

ここでなるほどと思ったのは、break や continue として発生させるエラーを、ただの空オブジェクトにしていることです:

var $break    = new Object();
var $continue = new Object();

これだけで一意性が保証されるので、break が投げられたのか、一般のエラーが発生したのかは比較オペレータで単純に判別できる、と。なかなか便利に使えそうなアイデアです。また、変数名にドル記号が使えるというのも驚きです。

追記:
Enumerable オブジェクトを 配列やハッシュ等にミックス・インするという、Rubyの 手法を踏襲している点も、JavaScript 的に目新しく、勉強になります。