読者です 読者をやめる 読者になる 読者になる

Life, Education, Death

プログラミング以外でも思ったことをつらつらと書きたい

AspectPHPを構想する

AspectJAspect指向を知った。そして、考えを改めた

AspectJ - Wikipediaという言語がある。
そしてアスペクト指向プログラミングというものがある。

この方法では絶対に、コードが書いてある通りに実行されているように見えなくて混乱を招くと思う。だからあんまり多用するのは控えて、使うとしてもドキュメントをちゃんと残して・・・ってことになるとずっと思っていた。

改心

例えば、Logを残したい。いくつも対象となるクラスがあって、その特定のメソッドが例外を発生されて、プログラムを終了させようとしているときに
Logを残したいって要望があったとする。通常考えられる方法はその対象メソッドをtry-catchで囲んで、Loggerクラスのメソッドをコールしてログが落ちるようにする。

でもこの場合の修正コード量が多いことや、それぞれのクラスに純粋には必要のないコードが増えていることが問題点としてあげられると思う。

そのときはAspect指向を使って、メソッドの例外発生時に呼ばれるコールバック関数を指定してやると解決できる。


おぉすばらしい。コード量も減るし、クラスの機能が純粋に絞られていく〜

AspectPHPを実装する

Javascriptなら関数の扱いが簡単で、定義済みの関数を編集することもできる。加えて、nativeでなければ関数の実装コードを参照することもできるので、結構簡単にできそうな気がしている。


でもJavascriptでは使いたい場面がまだないので実装はパスする。


PHPで下のようなコードがあって

function hoge(){
    echo 'hoge';
    // <- ここでログを出力したい
}

function hoge(){
    echo 'hoge';
    L:debug('ログ'); // <-これだとhogeに必要な機能以外が実装されている
}

下のようなfunction hogeにしたくなかったのでAspect指向PHPを実装し始めてみた。


最終的に上のコードが

function hoge(){
    echo 'hoge';
}

$aspect = AspectFunction( 'hoge' );
$aspect->addPointCut( 'after', ' L:debug('ログ');' );

こんな風になったら、hogeに変更なく実現ができるのでhogeを書いている人が知らなくてもいい状況が作れる。

無名関数はマジでハマる

ここに書いている通り、create_functionの作る関数の関数名は先頭にNULLが入っている。

なので、無名関数の中で前に作った無名関数を作ろうとすると都合が悪い。

$funcName = create_function('', 'echo "test";');
create_function('', $funcName.'();' );

とかすると、二つ目のcreate_functionがこける。たぶん、$funcNameが文字列になってしまったら、NULL文字があるのでそこで文字列終了と判定されて、正しく解釈されないのだと思う。


なので、ユニークな名前を作りながら指定されたコールバック関数を作っていくことにした。


今の開発環境がWindows版でPHP5.25でrunkitの関数が正しく動作しなくて、クラスに関する関数だけしか使えないようだ。

関数の振る舞いを変えられるようにならないと、目標が最後までいきそうにない。

できたこと

  • 特定のクラスのメソッドに前処理を挿入できる
  • 特定のクラスのメソッドに後処理を挿入できる
  • 特定のクラスのメソッドを入れ替えられる

という機能まで作った。
AspectJにある機能をできるだけ、実装したら便利かなと思っている。


今後の目標としては

をできたらいいなと思っている。最後はPEARライブラリ化!?

とか夢膨らむ。