QIQを試してみた
2008年4月7日
今度は、もどきではないクロージャの、PHPでの実装について。
先日の記事、『PHPでクロージャもどき』を書いた後、hsurさんからの指摘などもいただいて色々調べた結果、先の記事の方法ではcreate_functionを使う不便さを除けば、一般的なクロージャの機能は一通りそろえていることは分かった。
一方で、create_functionの不便さはいかんともしがたいと思っていた矢先、知ったのがこれ:
続々・Zend Engine Hack (クロージャもあるよ) (拡張モジュールもあるよ) - 讃容日記:
以前どこかで知ったPHPでのラムダの実装用のパッチというのは、QIQと名づけられたこのハックらしい。QIQとは、PHPの次という意味だそうな。
早速ダウンロードして使ってみた結果、先の記事でのhsurさんの宿題もちゃんと実行できた。
少し解説すると、ラムダの宣言内の、
QIQ、これはいい!ぜひとも、将来のPHPに導入してもらいたいものだ。
先日の記事、『PHPでクロージャもどき』を書いた後、hsurさんからの指摘などもいただいて色々調べた結果、先の記事の方法ではcreate_functionを使う不便さを除けば、一般的なクロージャの機能は一通りそろえていることは分かった。
一方で、create_functionの不便さはいかんともしがたいと思っていた矢先、知ったのがこれ:
続々・Zend Engine Hack (クロージャもあるよ) (拡張モジュールもあるよ) - 讃容日記:
以前どこかで知ったPHPでのラムダの実装用のパッチというのは、QIQと名づけられたこのハックらしい。QIQとは、PHPの次という意味だそうな。
早速ダウンロードして使ってみた結果、先の記事でのhsurさんの宿題もちゃんと実行できた。
<?php $count = 0; function newCounters() { global $count; $i = 0; $a=array(&$i,&$count); $f1 = static function (){ static $a; $i=&$a[0]; $count=&$a[1]; $count++; $i = $i + 1; return $i; }; $f2 = static function (){ static $a; $i=&$a[0]; $count=&$a[1]; $count++; $i = $i + 2; return $i; }; return array( $f1, $f2 ); } $cs1 = newCounters(); $cs2 = newCounters(); alert($cs1[0]()); //1 alert($cs1[0]()); //2 alert($cs1[1]()); //4 alert($cs1[1]()); //6 alert($cs2[0]()); //1 alert($cs2[0]()); //2 alert($cs2[1]()); //4 alert($cs2[1]()); //6 alert($cs1[0]()); //7 alert($cs1[0]()); //8 alert($count); //10 function alert($text){ echo htmlspecialchars($text)."<br>\n"; }
少し解説すると、ラムダの宣言内の、
static $a; $i=&$a[0]; $count=&$a[1];がミソである。ここを、『static $i,$count;』と記述すると、うまく行かない。QIQの仕様では『static』はあくまでローカルなスタティック変数であり、ラムダの外部の変数を参照しているわけではないようだ。外部変数を参照するために、このような簡単なコードを挿入する必要があるが、クロージャの『方言』の一つとして許される範囲内である。
QIQ、これはいい!ぜひとも、将来のPHPに導入してもらいたいものだ。