让我们考虑一个简单的Groovy DSL
execute {
sendNotification owner
sendNotification payee
}
执行是
public static void execute(Closure dslCode) {
Closure clonedCode = dslCode.clone()
def dslDelegate = new MyDslDelegate(owner: 'IncCorp', payee: 'TheBoss')
clonedCode.delegate = dslDelegate
clonedCode.call()
}
和自定义委托是
public static class MyDslDelegate {
def owner
def payee
void sendNotification(to) {
println "Notification sent to $to"
}
}
运行execute
块的预期结果是
Notification sent to IncCorp
Notification sent to TheBoss
实际的是
Notification sent to class package.OwnerClassName
Notification sent to TheBoss
问题是owner
是Groovy Closure
本身的保留属性,没有resolveStrategy
选项有助于将owner
值替换为来自委托的自定义值,因为Groovy { {1}}
getProperty
我的问题是,有人可以如何制定此限制并在自定义DSL中使用Closure
属性名称?
答案 0 :(得分:1)
这有点像黑客,但这应该可以让你得到你想要的东西,而不需要改变Groovy来源:
public static void execute(Closure dslCode) {
Closure clonedCode = dslCode.clone()
def dslDelegate = new MyDslDelegate(owner: 'IncCorp', payee: 'TheBoss')
clonedCode.@owner = dslDelegate.owner
clonedCode.resolveStrategy = Closure.DELEGATE_ONLY
clonedCode.delegate = dslDelegate
clonedCode.call()
}
答案 1 :(得分:1)
简单的答案是否定的,你不能。 'owner'是Groovy中的保留关键字,因此根据定义不能用作任意符号。即使有办法解决这个问题,你最好只使用一个与语言实现不冲突的名称 - 在Groovy中尤其如此,它一直有望完全重新设计其MOP,意思是你实施的任何黑客都可能在将来的版本中停止工作。
如果您解释为什么您愿意提供赏金并寻找解决此问题的方法,而不是仅仅将名称更改为不同的东西并完全避免问题,那么问题可能更有意义。保留符号是语言的一个非常基本的限制,并且试图解决它们似乎是非常不明智的。