如果我有一个附加到expando的闭包,并且闭包引用了expando上的值,就像这样......
def e = new Expando()
e.val = 'hi'
e.doit = { println delegate.val }
e.doit()
工作正常。并打印'hi'
如果我用长格式调用闭包
e.doit.call()
它会抛出错误
groovy.lang.MissingPropertyException: No such property: val for class: Script1
at Script1$_run_closure1.doCall(Script1.groovy:4)
at Script1$_run_closure1.doCall(Script1.groovy)
at Script1.run(Script1.groovy:6)
这是因为委托从e更改为脚本。为什么? 我认为e.doit()和e.doit.call()应该是相同的。
我可以手动更改代理 - 就像这样
def e = new Expando()
e.val = 'hi'
e.doit = { println delegate.val }
e.doit.delegate=e;
e.doit.call()
有关如何跳过委托的显式设置的任何想法?
答案 0 :(得分:1)
是的,有一个更好的主意。
当您知道为Expando
定义的闭包(动态方法)时,直接引用Expando实例(而不是委托),这只是一个动态bean。另一方面,当针对具体类进行测试时,相同的测试将产生预期结果:
def e = new Expando()
e.val = 'hi'
e.doit = {
println delegate.class.name
"$e.val Joseph"
}
assert e.doit() == 'hi Joseph'
assert e.doit.call() == 'hi Joseph'
class Test{
String a
def printA = {
println delegate.class.name
"$delegate.a Joseph"
}
}
def test = new Test(a: 'hi')
assert test.printA() == 'hi Joseph'
assert test.printA.call() == 'hi Joseph'
注意两个案例中println
的系统输出。