PHPでクロージャ

というわけでPythonをちょこちょこ使ってたので(主にGoogle Application Engineのため)、
クロージャを使うのが当たり前になりました。
でも、Pythonは言語仕様的にクロージャが使いやすくなっており、
PHPで言うなら

hoge.php
$x = 0;
function get($y) {
    $x += $y;   
    return $y;
}

----

require('hoge.php');
hoge.get(2);

こんな感じで簡単にクロージャが実装できるんですよね。

まあ、それは無理なので。。クロージャを使ったことが無い人に、クロージャのサンプルを上げるとすると、

function counter () {
    $v = 0;
    return function () use(&$v) {
        return $v++;
    };
}

$c1 = counter();
$c2 = counter();

echo($c1() . "\n");
echo($c1() . "\n");
echo($c2() . "\n");
echo($c1() . "\n");
echo($c2() . "\n");
echo($c1() . "\n");

wikiにも載ってるこんな感じのプログラムでしょうか。counterの返り値に無名関数を返して、$vをlexicalに使おうという感じのプログラムです。phpはuse()で使用するlexical変数を指定しなくてはいけないんですねー。変更も加えるので参照付き呼び出しです。
結果は、

0
1
0
2
1
3

こうなります。
便利ですか? まあクラスでやっても同じですねw

class Counter
{
    private $v = 0;
    public function inc()
    {   
        return $this->v++;
    }   
}

$c1 = new Counter();
$c2 = new Counter();

echo ($c1->inc() . "\n");
echo ($c1->inc() . "\n");
echo ($c2->inc() . "\n");
echo ($c1->inc() . "\n");
echo ($c2->inc() . "\n");
echo ($c1->inc() . "\n");

本当は名前空間を汚さないように、Javascriptのように

(function () {
    function () {
        // hogehoge
    }
})()

こう使いたいんですけど、最後の()で関数実行が出来ないんですよね。
PHPの無名関数は返り値に使うか変数に入れるかしないといけないみたいです。。
残念。

タイトルとURLをコピーしました