プログラミング

QIQを試してみた

2008年4月7日

今度は、もどきではないクロージャの、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に導入してもらいたいものだ。

コメント

コメントはありません

コメント送信