@BaseScriptアノテーションはscriptをインクルードするのに使えます
Groovy 2.2以降、@BaseScriptアノテーションというのが導入され、Scriptの基底クラスを指定することができる*1ようになりました。
これは主目的としては、専用目的の便利機能追加・DSLの作成だと思いますが、単にscriptをインクルードするのにも使えます。
例えば、以下の「OtherScript.groovy」をクラスパスの通ったところか、あるいはカレントディレクトリに配置しておきます。
// OtherScript.groovy def methodOfOtherScript() { "i'm methodOfOtherScript1" } def methodOfOtherScript1() { "i'm methodOfOtherScript2" } println "this is otherScript!" a=3
これを呼び出す、mainscript.groovyでは以下のように@BaseScriptアノテーションを指定します。
import groovy.transform.BaseScript @BaseScript OtherScript _ super.run() println methodOfOtherScript1() println methodOfOtherScript2() println a
すると以下のとおり。
$ groovy mainscript.groovy this is otherScript! i'm methodOfOtherScript1 i'm methodOfOtherScript2 3
バインディング変数も引き継がれます。
main側のスクリプトを起点には探索してくれないようですが*2、OtherScriptのメソッドが修飾無しでmainscript.groovyから呼び出せます。ちなみに呼びだされるクラスは、大文字で始まらないと認識してくれません。つまり「otherscript.groovy」では駄目でした。
これ、前から欲しいと思ってたんだよね。呼ばれる側をクラス定義+staticメソッドにしてstatic importするとか、でも元のスクリプトをスクリプトとして実行できなくなるし、それならスクリプトのままならnewしてインスタンスメソッドとして呼ぶとか、でもバインディング変数の引き継ぎとか駄目だし、mixinとかではあまり上手くいかないし*3。
でもこの方法でも、1つのスクリプトで複数のscriptをimportすることは、できませんね。
ここは、ScriptがTraitだったら良かったのにな*4、ってところでしょう。
(追記2014/4/26)
バインディング変数は引き継げませんが、@Delegate+@Fieldでこんなのも可能だと今気づいた。
import groovy.transform.* @Field @Delegate OtherScript a = new OtherScript() @Field @Delegate SomeScript b = new SomeScript() println methodOfOtherScript1() println methodOfOtherScript2() println methodOfSomeScript1() println methodOfSomeScript2()
これなら複数のスクリプトもincludeできますや。
こっちの方がいいかも^^;