XOOPS Cube コア 0.9 のデリゲート

v1.0では新しいメッセージ通信機構を取り付ける予定なんじゃけど、その前に v0.9 レベルで実装されとるデリゲートについて、もっぺん考えてみる。

 v0.9 のデリゲートシステム XCube_Delegate は「コールバックのための統一手続き」という仕様で、間接ジャンプのやり方を開発者の間で統一させるんがゴールだった。と同時に、 XOOPS のような(MODな)システムでは必須となる、「通信相手のモジュールがインストールされていなくても、レシーバー登録を実行してエラーにならない機構」として通知センターである XCube_DelegateManager を導入した。これでランタイムでは preload を利用した動作カスタマイズが可能になった。

 XCube_DelegateManager は PHP の実行時の逐次コンパイルの特性を緩衝することと、いわゆるブロードキャストメッセージングに相当する2つの役割がある。ただし動作的には同期タイプなので、並列ポリシー下では利用頻度は激減することになるじゃろう。

 ともかく、この「通信相手がおらんでもコンパイル通って、フェータルエラーにならん」という特性は、開発者がこれまでどういうジャンルの開発でどういう経験をしとったかで受け止め方が大きゅう変わるもんになった。ある種のプログラマにとっちゃあ毎日顔をつきあわせてとる機構でも、別のプログラマにとっては見たこともないケッタイな機構じゃし、1アプリの開発を完遂する業者さんにとってみりゃあ、エラーが隠れるんは便利などころかやれんじゃろう。

 個人的には、手元で1アプリとしてビルドする場合、「通信相手がおらんのにコードを書く」なんてことはありえんけー、業者さんは無理して使う必要はないと思う。ウェブの世界のことはよー分からんけど、こりゃあくまで XOOPS の MOD 文化サポートと思ってもろうていい。

 でも、個人的には今後は MPI 的なプログラミングは増えるじゃろーけー、いっぺん食っとくのも悪ぃないと思うとるんじゃけど。XCube_Delegate も XCube_DelegateManager もメカニクス的にはレガシーなもんじゃし、こういう仕組みの世界を知っとっても損はないじゃろ……たぶん……

 デリゲートの問題点としては以下がある。

特性が変化する

 同じ「デリゲート」なのに、通知センターである XCube_DelegateManager を通した場合と、そうでない場合では動作や特性が大きく変わる。もちろんコールの仕組みじゃけー、コードレベルで共有部分があるのはええんじゃけど、両方とも「デリゲート」にしたのは、ようなかった。

 個人的にはデリゲートでコードを書いて、公開したかったら通知センターに登録するというイメージだった。

追いにくい

 マルチスレッドと間接ジャンプはコード見ただけじゃ分からんです。ブレークポイントで引っ掛けてコールスタックで追っかけるなり、ステップ実行するなりがええと思うんじゃけど……解決案として出されたんは、 XCube_DelegateManager に登録したデリゲートでは、コール時にも XCube_DelegateManager を使うこと。

 結果動作は変わらんわけじゃし、これはこれでありじゃと思うんじゃけど、ただ、数年後には確実に XOOPS とかの領域にもマルチコア、マルチスレッドが来ることを考えると、デバッガを使う習慣も今のうちに普及させたい。

関数ポインタ寄り

 デリゲートの使い方が普及してきた頃、「デリゲートだけでコードが書けるんじゃないか」という人がちらほら出てきた。実際、動的結合のみで動いてるランタイムとか、言語とか実際にありますけー、書けるんは世間で証明されとるし、実際便利です。

 ただ、 XCube_Delegate は1関数単位だから、継承と比べると設定効率が悪く、しかも、重い!重いんじゃ! そこで、 v1.0 では Objective Delegate という、一般的にいわれるデリゲートに近い実装*1の仕組みを追加しようと思っとる。一応手元ではもうできとるけー、サンドボックスに近くコミットします。

重い

 さっきも書きましたが、クラス使っとるけー重いです。しゃあないけど……


v1.0 では、読みにくくてもえーけー速いメッセージングを実装したい。同期非同期の違いはあるけど、デリゲートの内部にも適用できるもんならそうしたい。

最新のPHPであれば、ラムダのような関数型があるけーデリゲートの重要性は下がったはず。……と思ったら結構定義使いにくいのね……>ラムダ

*1:.NET Framework のアレは結構プリミティブな関数ポインタでした。じゃけー好きなんじゃけど