宣言されたクラスが eval 間に存在しないという意味についてはよくわかりません。次の 2 つのスクリプトは、次々に評価されると期待どおりに機能します。
class C {{println 'hi'}}
new C()
...
new C()
ただし、メソッドはそれらを宣言したクラスにバインドされ、GroovyShell はインスタンスごとに新しいクラスを作成します。どのスクリプトの戻り値も必要なく、それらが真のスクリプト (メイン メソッドを持つクラスではない) である場合は、評価されたすべてのスクリプトの最後に次を追加できます。
Class klass = this.getClass()
this.getMetaClass().getMethods().each {
if (it.declaringClass.cachedClass == klass) {
binding[it.name] = this.&"$it.name"
}
}
戻り値に依存する場合は、評価を手動で管理し、解析の一部としてスクリプトを実行できます (警告、テストされていないコードが続きます。例示的な使用のみを目的としています)...
String scriptText = ...
Script script = shell.parse(scriptText)
def returnValue = script.run()
Class klass = script.getClass()
script.getMetaClass().getMethods().each {
if (it.declaringClass.cachedClass == klass) {
shell.context[it.name] = this.&"$it.name"
}
}
// do whatever with returnValue...
最後にもう 1 つ注意事項があります。静的に型付けされた変数は、バインディングに格納されないため、eval 間で保持されません。したがって、前のスクリプトでは、変数「klass」はスクリプトの呼び出し間で保持されず、消えます。それを修正するには、すべての変数を最初に使用するときに型宣言を削除するだけです。つまり、それらはバインディングに対して読み取られ、書き込まれます。