Continuation 0.0.3

php_continuation-0.0.3devel.tgz


昨日予告してたやつです。

  • array co_inspect(resource continuation $co)
    • continuation にバインドされている変数のコピーを取得する。


アーカイブに付属の使用例だと何が嬉しいのかよく分からないと思うので、別の例をば。
このモジュールを使うと、PHP でもクロージャのようなことができます。
例えば Rubyクロージャのサンプルでよく見かける "highPaid"クロージャを返すメソッド "paidMore" はこのように書けます。

<?php
function paidMore($amount)
{
    return co_create(create_function('$e', 'return $e->salary > $amount;'));
}

$highPaid = paidMore(150);

$emps = array(
    (object)array('name' => 'Jon',  'salary' => 200),
    (object)array('name' => 'Bon',  'salary' => 100),
    (object)array('name' => 'Jovi', 'salary' => 150),
);

foreach ($emps as $emp) {
    printf("%s is the %s-paid.?n", $emp->name,
        co_call($highPaid, array($emp)) ? 'high' : 'low');
}

ブロックの代わりに create_function()、クロージャの call メソッドの代わりに co_call() を使っていますが、見た目だけは似た感じにできました。最後の foreach で台無しですが。


配列で continuation に渡す引数リストを指定する方法はダサいしミスの元になりやすいので、次のバージョンでは後方互換性を無視して可変長引数にしようと思います。


追記:
今は実行時にローカル変数用のシンボルテーブルをプリセットする方法で実現しているのですが、opcode のスタティック変数用領域を弄ればもっと純粋にクロージャっぽいことができる・・・はず。