php_iovm 0.3.0

php_iovm-0.3.0.tgz

説明を書く前にバージョンアップしてしまいました。
ビルドにはIoの最新版、Io-2007-10-03かgitの開発版が必要です。IoStatePrintCallbackの引数が変わったのでIo-2007-05-28ではビルドできません。
変更箇所は下記のとおりです。


PHP/Io共通:

  • PHP6のUnicode文字列からIoのSequenceへの変換に対応。IoのSequenceからPHPUnicode文字列への変換はしない。
  • zval <-> IoObjectの相互変換で参照/WeakLinkに対応。


PHPのみ:

  • スタティックメソッドIoState::staticDoCString($code), IoState::staticDoFile($path)を廃し、代わりに関数io_eval($code), io_load($path), io_peval($code), io_pload($path)を追加。
    • io_eval, io_loadは呼び出しの度にIoStateを初期化・開放し、io_peval, io_ploadはひとつのstateを共有する。
    • io_peval, io_ploadで使われるstateはどちらかが最初に呼び出される際に初期化され、プログラムの終了時に開放される。


Ioのみ:

  • PHPのクラスのインスタンスを生成できるようになった。(PHP new(className[, arg1[, arg2[, ...]]]))
  • Zvalオブジェクト (PHPの変数) を生成・更新できるようになった。(PHP value(someValue), Zval setValue(newValue))
    主にクラス定数やスタティックメソッドを利用するために使うことを想定。
  • Zvalオブジェクトでforeachが利用できるようになった。
  • メソッドconstantがconstに名称変更。
  • メソッドrawXxxがzXxxに名称変更。


そしてIoで使えるPHPオブジェクトとZvalオブジェクトのメソッド (スロット) 一覧です。

PHPオブジェクト

メソッド引数戻り値説明
echo 任意のオブジェクト × 任意の数 nil PHPの出力ストリームに文字列を書き込む。
write, writeln, print, println等のメソッドでもPHPの出力ストリームに書き込むので明示的に使う必要はない。
value 任意のオブジェクト Zval (型に応じて自動変換) オブジェクトをZvalに変換する。
new Sequence (+ 任意のオブジェクト × 任意の数) Zval (新たなインスタンス) 指定されたPHPクラスのインスタンスを生成する。
二番目以降の引数はコンストラクタに渡される。
call Sequence (+ 任意のオブジェクト × 任意の数) Sequence, Number, List, Map, Date
(型に応じて自動変換)
指定されたPHP関数をコールする。
二番目以降の引数は関数に渡される。
参照を引数にとる関数では、引数がZvalオブジェクトの場合だけ値が更新される。
const Sequence PHP定数を取得する。
global Sequence PHPグローバル変数を取得する。
var Sequence PHPローカル変数を取得する。
zCall Sequence (+ 任意のオブジェクト × 任意の数) Zval (PHPの値をそのまま格納) 指定されたPHP関数をコールする。
二番目以降の引数は関数に渡される。
参照を引数にとる関数では、引数がZvalオブジェクトの場合だけ値が更新される。
zConst Sequence PHP定数を取得する。
zGlobal Sequence PHPグローバル変数を取得する。
zVar Sequence PHPローカル変数を取得する。

Zvalオブジェクト

メソッド引数戻り値説明
asNative - Sequence, Number, List, Map, Date
(型に応じて自動変換)
Ioネイティブの型に変換した値を取得する。
asNumber - Number Numberに変換した値を取得する。
asString - Sequence Sequenceに変換した値を取得する。
setValue 任意のオブジェクト self 値を更新する。
zType - Sequence PHP変数としての型名を取得する。
レシーバのPHP変数としての型がオブジェクトならクラス名、リソースならリソース型も付加される。

Zvalオブジェクト (文字列型(クラス名)、オブジェクト型のみ)

メソッド引数戻り値説明
call Sequence (+ 任意のオブジェクト × 任意の数) Sequence, Number, List, Map, Date
(型に応じて自動変換)
レシーバのPHP変数としての型が文字列ならクラスのスタティックメソッド、オブジェクトならインスタンスメソッドをコールする。
二番目以降の引数はメソッドに渡される。
参照を引数にとるメソッドでは、引数がZvalオブジェクトの場合だけ値が更新される。
const Sequence クラス定数を取得する。
var Sequence レシーバのPHP変数としての型が文字列ならクラスのスタティックプロパティ、オブジェクトならインスタンスプロパティを取得する。
zCall Sequence (+ 任意のオブジェクト × 任意の数) Zval (PHPの値をそのまま格納) レシーバのPHP変数としての型が文字列ならクラスのスタティックメソッド、オブジェクトならインスタンスメソッドをコールする。
二番目以降の引数はメソッドに渡される。
参照を引数にとるメソッドでは、引数がZvalオブジェクトの場合だけ値が更新される。
zConst Sequence クラス定数を取得する。
zVar Sequence レシーバのPHP変数としての型が文字列ならクラスのスタティックプロパティ、オブジェクトならインスタンスプロパティを取得する。

Zvalオブジェクト (配列型、オブジェクト型のみ)

メソッド引数戻り値説明
foreach (Map foreachと同じ) ループで最後に評価された値 配列、オブジェクトのプロパティ、イテレータの各要素についてメッセージを実行する。
キーと値は型に応じて自動変換される。
zForeach (Map foreachと同じ) ループで最後に評価された値 配列、オブジェクトのプロパティ、イテレータの各要素についてメッセージを実行する。
キーと値はZvalとして代入される。

ちょっとしたサンプル

このエクステンションの機能の一通りの使い方はアーカイブの中のtestsとexamplesにあるので、PHPにIoを組み込めて何が嬉しいかがわかる例をひとつ。
先に言っておくと、IoでMeCabが使えるのが嬉しいわけではありません (個人的には嬉しいけど本題ではない)。PHPの変数経由とはいえ、Ioで日本語が使えるのが嬉しいのです。Ioはとても面白い言語なのだけど、マルチバイト文字列リテラルが書けないという、致命的な問題があるので。


io-mecab.php:

<?php
$s = '隣の客はよく柿食う客だ';

ob_start();
?>
printZvalType := method(obj, writeln(obj type, ":", obj zType))

opt := Map clone
opt atPut("-d", "/opt/local/lib/mecab/dic/ipadic-utf8")
mecab := PHP new("MeCab", opt)
printZvalType(mecab)

node := mecab zCall("parseToNode", PHP zVar("s"))
printZvalType(node)
bos := node const("BOS");
eos := node const("EOS");

node zForeach(id, n,
    stat := n var("stat")
    if (stat == bos,
        "BOS" println,
        if (stat == eos,
            "EOS" println,
            writeln(id, "\t", n var("surface"))
        )
    )
)
<?php
io_eval(ob_get_clean());


output:

Zval:object(MeCab)
Zval:object(MeCab_Node)
BOS
1	隣
5	の
8	客
11	は
24	よく
31	柿
37	食う
44	客
48	だ
EOS