BeInteractive!

ブロック付きメソッド呼び出しとは、Rubyにある機能で、簡単に言えば関数自体を引数に渡してメソッドを呼び出しちゃうものです。(一般にはlambda式とかクロージャとか言われてる?)

[1,2,3,4].each {|item|
 print item
}

これで、1~4が表示されます。Rubyやforeach的なモノを知らない人にはちょっと分かりにくいでしょうか。{}で囲まれた部分がブロック(関数)で、||で囲まれた部分が引数です。.eachメソッドを呼び出すと、各要素毎に、要素を引数として、ブロックが呼び出されるのです。

ちなみに、PHPで書けばこうです。

foreach(array(1, 2, 3, 4) as $item)
{
 echo $item;
}

さて、ここまで書いて何が言いたいか分かった人も結構いると思います。

ブロック付きメソッド呼び出しは、ActionScriptでも出来るのです。

とりあえず、実装は後回しにして、実装後の使用例を見て見ましょう。組み込みのArrayクラスにeachメソッドを実装した例が次のコードです。

var list:Array = [1, 2, 3, 4];
list.each(function(item)
{
 trace(item);
});
出力:
1
2
3
4

なにやら怪しげな感じですが、良く見るとさっきのRubyのコードとほとんど同じです。各要素毎に、要素が引数itemに入れられて、ブロック{}が実行されます。

あえて、eachを使わないコードで書くとこうなります。

for(var i:Number=0; i<list.length; i++)
{
 var item = list[i];
 trace(item);
}

比べると、ループがかなり簡潔に書けているのがお分かりいただけるでしょうか。余計な変数iもいりません。

実は凄い所はそれだけではありません。なんと、eachの中から、外で定義した変数にアクセスできます。

var f:Number = 3;
list.each(function(item)
{
 trace(item*f); //各要素をf倍しながら表示
});

これが出来ると、次のようなメソッドを作ることが出来ます。

// nよりも小さい要素のリストを返すメソッド
function getListLessThan (n:Number) : Array
{
 var result:Array = new Array();
 list.each(function(item)
 {
  if(item < n)
  {
   result.push(item);
  }
 });
 return result;
}

なかなか凄いと思いませんか?

では、お待ちかね実装を見て見ましょう。かなり簡単です。

Array.prototype.each = function (closure:Function) : Void
{
 for(var i:Number=0; i<length; i++)
 {
  closure(this[i]);
 }
}

単純に、引数に渡されたメソッドを、各要素を引数にして呼び出しているだけです。このテクニックはかなり汎用的なので、何処でも使えます。

ちなみに、このeachメソッドの実装を置き換えることで、全てのループの方法を変更することも出来ます。

勿論、ループ毎にメソッド呼び出しが入るのでメソッド呼び出し分のオーバーヘッドはあるのですが、速度はそれほど気にならない場面では大いに使えるのではないでしょうか。是非使ってみてください。JavaScript(Ajax)でも出来ます。

#但し、まだ補足があります。それはまた次に。

この記事へのトラックバック

トラックバックはありません。

TrackBack URL:

http://www.be-interactive.org/trackback.php?id=40

この記事へのコメント

コメントはありません。

コメント書き込み:

カテゴリ

タグ

アーカイブ