RSKit 0.2.0: RSKit, Scope, Klosure

php_rskit-0.2.0.tgz
RSkit::mixin()で任意の数のクラスを一度にMix-inできるようにしたり、ScopeクラスにcallメソッドとcallWithArgumentsメソッドを追加したほか、実験的な抽象クラス“Klosure”を追加しました。
また、Scopeクラスでinclude_pathが指定できないバグを修正しました。
runkitと併用すればPHPにこれまでにない自由さと変態度をもたらします。

RSKit

クラスや関数を扱うユーティリティ。

API
static public bool RSKit::mixin(string $target_class, string $source_class, ...)

$target_classに$source_classのインターフェイス、クラス定数、プロパティ、メソッドをMix-inする。
$target_class、$source_classともにユーザ定義クラスでなければならず(インターフェイスや抽象クラスも不可)、$source_classに他のクラスを継承しているクラスを指定することはできない。Mix-inするクラスは複数指定できる。

static public string RSKit::cloneFunction(callback $callable)

関数またはメソッドを複製する。複製されたメソッド・関数はオリジナルとは別のスタティック変数テーブルを持つ。
戻り値は新たに作成された関数名。

static public bool RSKit::setStaticVariable(callback $callable, string $name, mixed $value)

関数またはメソッドのスタティック変数を更新する。
スタティック変数として扱われる変数はスクリプトコンパイル時に決定されるので、新たなスタティック変数を定義することはできない。

static public bool RSKit::setStaticVariables(callback $callable, array $values)

連想配列からスタティック変数を一括で更新する。

使用例

mixin():

<?php
class BaseClass {}

class Module1
{
    private $compile_class_name;
    private $runtime_class_name;

    public function __construct()
    {
        $this->compile_class_name = __CLASS__;
        $this->runtime_class_name = get_class($this);
    }
}

class Module2
{
    public function getInfo()
    {
        return array('compile' => @$this->compile_class_name,
                     'runtime' => @$this->runtime_class_name);
    }
}

RSKit::mixin('BaseClass', 'Module1', 'Module2');

$obj = new BaseClass;
print_r($obj->getInfo());

結果:

Array
(
    [compile] => Module1
    [runtime] => BaseClass
)


cloneFunction() and setStaticVariables():

<?php
function countup()
{
    static $n = 0, $i = 1;
    return $n += $i;
}

$countdown = RSKit:: cloneFunction('countup');
RSKit::setStaticVariables($countdown, array('n' => 10, 'i' => -1));

var_dump(countup(), $countdown());
var_dump(countup(), $countdown());
var_dump(countup(), $countdown());

結果:

int(1)
int(9)
int(2)
int(8)
int(3)
int(7)

Scope

continuationエクステンションの焼き直し。ローカル変数のシンボルテーブルと読み込みパスを指定して関数・メソッドを呼び出したり、コードを評価したり、スクリプトを実行したりする。値の変更や新しく宣言された変数は維持される。
プロパティを操作することによって(マジックメソッド経由で)シンボルテーブルに格納されている変数を更新・取得することもできる。

API
static public mixed Scope::staticLoad(array $symbol_table, string $path, ...)

連想配列で変数のシンボルテーブルを指定してスクリプトを実行する。戻り値は最後に実行したスクリプトがreturnした値。

public void Scope::__construct([array $symbol_table[, string $include_path]])

コンストラクタ。$symbol_tableが省略された場合、アクティブなスコープを取り込む。$include_pathでloadメソッド等で使用される読み込みパスを設定できる。

public mixed Scope::calll(callback $callable[, mixed $arg, ....])

ユーザ定義関数を呼び出す。ユーザ定義関数内で初期化されていない変数はScopeオブジェクトのシンボルテーブルを参照する。

public mixed Scope::callWithArguments(callback $callable, array $args)

配列で引数を指定してユーザ定義関数を呼び出す。

public bool Scope::evaluate(string $code)

コードを評価する。

public mixed Scope::load(string $path, ...)

スクリプトを実行する。戻り値は最後に実行したスクリプトがreturnした値。

public array Scope::getSymbolTable(void)

シンボルテーブルを設定する。戻り値は古いシンボルテーブル。

public string Scope::getIncludePath(void)

読み込みパスを設定する。戻り値は古い読み込みパス。

public array Scope::setSymbolTable(array $symbol_table)

シンボルテーブルの複製を取得する。

public string Scope::setIncludePath(string $include_path)

読み込みパスを取得する。

Klosure

抽象クラスで、このクラスを継承したクラスが初期化されるとき、未初期化または値がnullのプロパティの値をアクティブなスコープから取り込む。コンストラクタでプロパティを初期化するのが面倒なときに。

使用例
<?php
class TestClosure extends Klosure
{
    public $foo;
    protected $bar;
    private $baz;
}

$foo = 1; $bar = 2; $baz = 3;
$obj1 = new TestClosure;

$foo = 'hoge'; $bar = 'fuga'; $baz = 'piyo';
$obj2 = new TestClosure;

print_r($obj1);
print_r($obj2);

結果:

TestClosure Object
(
    [foo] => 1
    [bar:protected] => 2
    [baz:private] => 3
)
TestClosure Object
(
    [foo] => hoge
    [bar:protected] => fuga
    [baz:private] => piyo
)