class Box {
Closure click
Box () {
click = {}
}
void onClick() {
click()
}
}
class TextBox extends Box {
List<String> content
TextBox (String[] a) {
super()
content = a
}
}
class Main {
public static void main(String[] args) {
Main m = new Main()
}
Main() {
String[] a = ["Hello world!"]
Box b = new TextBox(a)
b.click = {content.add("You clicked this box!")}
b.onClick() //throws Exception
}
}
(上記は明らかに簡略化したものです。実際には、クラスはもう少し複雑で、onClick() の呼び出しは JFrame をクリックすることによるものです)
今、それを実行しようとすると (つまり Main.main() を実行すると)、例外が発生します: Exception in thread "AWT-EventQueue-0" groovy.lang.MissingPropertyException: No such property: content for class: Main
明らかに、何らかの理由で、List が呼び出された場所から、TextBox や Box ではなく、Main で List を検索しています。これも所有者とデリゲートを使用してみましたが、それらはすべてメインも指しています。これを引数として指定することで、なんとか機能させることができました:
...
void onClick() {
click(this)
}
...
b.click = {it.content.add("You clicked this box!")}
しかし、クロージャーがどこから呼び出されたのかを知るためだけに、実際に「this」をクロージャーに渡す必要があるのは奇妙に思えます。よりエレガントなソリューションはありませんか?また、TextBox スコープに入ることが実際に不可能な場合でも、Box スコープに入ることができるのでしょうか。