Groovyのcall()をプロパティに対して適用するには?
TLDR
Groovyの call()
はローカル変数に対しては機能するが、クラスのプロパティに対しては機能しない。解決法をご存じでしたら教えてください。
やりたいこと
変数に関数呼び出し演算子を適用した場合の処理を書きたいことがあります。例えば、下記のようにクロージャでプロパティを設定できたら便利です。
def x = new X() x { value = 100 }
そんな時は当該クラスに call()
メソッドを定義します。
class X { def value = 50 def call(Closure c) { def cloned = closure.clone() as Closure cloned.resolveStrategy = Closure.DELEGATE_FIRST cloned.delegate = this cloned.call() } } def x = new X() assert x.value == 50 // やりたいこと x { value = 100 } assert x.value == 100
しかし、このインスタンスを他クラスのプロパティにするとうまくいきません。
class Y { def x = new X() } def y = new Y() y.x { value = 1000 } assert y.x.value == 1000
そんなメソッドはないというエラーが発生します。
groovy.lang.MissingMethodException: No signature of method: Y.x() is applicable for argument types: (Script1$_run_closure2) values: [Script1$_run_closure2@69bfa8] Possible solutions: is(java.lang.Object), any(), getX(), use([Ljava.lang.Object;), any(groovy.lang.Closure), wait() at Script1.run(Script1.groovy:26)
とりあえず、プロパティと同名のメソッドを定義すれば解決します。
class Y { def x = new X() def x(Closure closure) { //... } }
しかし、すべてのプロパティに対して同名のメソッドを書くのは冗長です。何かいい方法をご存じでしたら教えてください。