コルーチンもどき by 継続

php_continuation-0.0.5.tgz


既存の関数をクロージャ化する関数を追加しました。

  • string co_enclose(callback $func[, array $env_vars[, int $flags]])

これは co_make_callable(co_create($func, $env_vars, $flags)) を短く書けるようにしたものです。
引数の詳しい説明は一昨日のエントリの co_create() および定数の項を参照してください。


これを使ってコルーチンもどきを作ってみましょう。
コード:

<?php
function pseudo_coro_impl()
{
    switch (++$coro_state) {
      case 1:
        var_dump($param1, $param2);
        return;
      case 2:
        $str = str_repeat($param1, $param2);
        return;
      case 3:
        var_dump($str);
        return;
    }
}

function pseudo_coro_init($param1, $param2)
{
    $coro_state = 0;
    return co_enclose('pseudo_coro_impl', null, CONTINUATION_ALL);
}

$coro1 = pseudo_coro_init('foo', 6);
$coro2 = pseudo_coro_init('bar', 2);

$coro1();
$coro2();

$coro1();
$coro2();

$coro1();
$coro2();

結果:

string(3) "foo"
int(6)
string(3) "bar"
int(2)
string(18) "foofoofoofoofoofoo"
string(6) "barbar"

状態管理に自前で $coro_state をインクリメントしているのが不細工なのは置いといて、ちゃんと return したときのローカル変数の値が $coro1 と $coro2 で個別に保持されていますね。
continuation モジュールを使うと PHP のスコープではできなかったことができるようになります。