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に導入してもらいたいものだ。