我正在编写一个包含许多全局属性和Closures的大型Groovy脚本。所有Closures都用于向现有类添加新方法,例如:
myProperty = 'foo'
// ...more script code...
class MyClass {
def myProperty = 'default'
}
// ...more script code...
MyClass.metaClass.evaluate = { ->
myProperty = 'bar'
}
def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "default" instead of "bar"
我的意图是Closure的myProperty
引用委托类'myProperty
而不是全局代表类。我找到了几种方法来解决这个问题:
1)在闭包内明确取消引用delegate
:
MyClass.metaClass.evaluate = { ->
delegate.myProperty = 'bar'
}
def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "bar" as desired
2)将闭包的解析策略设置为DELEGATE_ONLY:
def evalClosure = { ->
myProperty = 'bar'
}
evalClosure.resolveStrategy = Closure.DELEGATE_ONLY
MyClass.metaClass.evaluate = evalClosure
def mc = new MyClass()
mc.evaluate()
println mc.myProperty // prints out "bar" as desired
我更倾向于使用方法#2来避免在我的闭包中遍布“委托”,但我不喜欢为我创建的每个闭包设置解析策略。
默认情况下,如何告诉Groovy对所有Closures使用DELEGATE_ONLY解析策略?这甚至可能吗?
答案 0 :(得分:1)
我无法更改默认授权策略,只要我能看到您有两个选项:
将您的脚本拆分为类(因此您没有脚本级别myProperty
和级别myProperty
在同一范围内)
编写一种更改resolveStrategy
的方法,并在设置metaClass
时调用此方法,即:
def only( Closure c ) {
c.resolveStrategy = Closure.DELEGATE_ONLY
c
}
MyClass.metaClass.evaluate = only { ->
myProperty = 'bar'
}