2007年5月29日火曜日

grails-wicket plugin を読む (2)

2回目. ここでは実は "Convention over Configuration" の実態が実は, grails がインタプリタ (メタオブジェクト) の集合になっていることだというのが分かる. ではいってみよう...



プラグイン定義クラスの規約を決めているやつは, 実はここにいる.



org.codehaus.groovy.grails.plugins.GrailsPlugin



Java インタフェースだが, スーパーインタフェースは Spring Framework の中にある ApplicationContextAware. ApplicationContextAware を実装するクラスは Spring Framework の恩恵を得ることができる, ととりあえずは思っておく.



GrailsPlugin には「規約」に相当する (≒ Java Interface に相当する), つまりプラグイン定義クラスで def すべきプロパティが文字列として定義されている. 例えば



String DO_WITH_DYNAMIC_METHODS = doWithDynamicMethods;

String WATCHED_RESOURCES = watchedResources;

String EVICT = evict;

// ......




また実装クラスはそれらプロパティへのアクセッサを定義しなさい, となっている. 例えば



void doWithWebDescriptor(GPathResult webXml);

String getName();

String getVersion();

// .......




つまり GrailsPlugin の実装クラスは, プラグイン定義クラスのインタプリタなのだ!



GrailsPlugin を実装しているのは



org.codehaus.groovy.grails.plugins.AbstractGrailsPlugin



で, つまりプラグイン定義クラスのインタプリタのひな形というわけ. これはさらに AbstractGrailsClass のサブクラスになっている. AbstractGrailsClass は Grails 全体で使われる汎用インタプリタのひな形だ. AbstractGrailsClass のサブクラスには他に DefaultGrailsDomainClass などがあるが, これはドメイン・クラス定義クラスのインタプリタということになる.



org.codehaus.groovy.grails.plugins.DefaultGrailsPlugin



AbstractGrailsPlugin を具体化したもの, つまりデフォルトのプラグイン定義クラス・インタプリタと言える. この中身を見てみると, new するときには対象となるプラグイン定義クラス (例えば WicketGrailsPlugin) が渡される. これがつまりインタプリタに与えられるプログラムということになる. このプログラムのシンタックスは前述の GrailsPlugin が決めているわけだ.



だから, プラグイン定義クラスに定義されていない変数 application が出現したとしても, それをどうするかはインタプリタの都合次第ということになる. インタプリタの中を見てみると application という変数には GrailsApplication が入っている (doWithRuntimeConfiguration() メソッド内). 他にもこのクロージャの中では manager, plugin, parentCtx, resolver という変数が使えることが分かる.



GrailsApplication は多分 Grails アプリケーションのファサードだろうと想像がつく. けど, これが実際にどんな変数とメソッドを持っているかは, GrailsApplication の JavaDoc のようなドキュメントかソース・コードを見ないと分からない. そこが Grails の弱点だとは思う. つまりインタプリタの世界 (Java) とプログラムの世界 (Groovy/Grails) が分離している. だから何かしようと思うと二つの世界を行ったり来たりしなければならないことになる. Lisp や Smalltalk だとこの二つの世界は同じ言語で記述され, かつ優秀な開発/デバグ環境が存在するのだが...



ちなみにここで「インタプリタ」と呼んでいるものは「メタオブジェクト」と呼び変えてもよい. オブジェクトの挙動を決めているオブジェクトだから.



続く...