アサーションのコンパイル(アサーションをアスペクト&メタデータで実装)
Groovyのスクリプトはバイトコードにコンパイルすることができます.
GroovyラボのGroovyの埋め込みによると,GroovyClassLoader
を使えばいいみたい.
GroovyスクリプトをGroovyClassLoader
に渡すと,GroovyObject
をimplements
したクラスがダイナミックに作られて,そのClass
が返されるので,newInstance()
すれば,インスタンスを得ることができる,と.
そしてinvokeMethod(String method, Object args)
でrun
というメソッドを呼び出せば,スクリプトを実行できるらしい.
Binding
はどうするんだろう? スクリプトから利用できるように変数を設定してGroovyShell
のコンストラクタに渡していたあのBinding
を,GroovyObject
に渡すには?
どうやら,Binding
ではなく,そのキーと値のペアをsetProperty(String name, Object newValue)
で設定しろということらしい.うーむ.面倒だな.
なんか,もう少し使いやすい方法はないのかなぁ? ということでJavaDocを眺めてみたところ,なぁんだ,GroovyShell#parse(String)
なんてのがあるじゃないですか.
これにスクリプトを渡すと,中ではGroovyClassLoader
が呼び出されて,コンパイルして得られるGroovyObject
をラップしたScript
のインスタンスが返ってきます.じゃなくて,コンパイルされてできるクラスはScript
のサブクラスらしい.
Script
クラスには,setBinding(Binding)
メソッドがあります.さらにrun()
メソッドもあるので,こっちの方が扱いやすそう.
ただ,この場合でもsetBinding(Binding)
〜run()
は排他的に実行しないといけないと思われるので,synchronized
する必要がありそう.run(Binding)
でスレッドセーフに実行というわけにはいかないのですかねぇ.まっいっか.