我正在创建一个构建器,它接受Groovy闭包作为标记。但是我在使用嵌套闭包捕获方法调用时遇到问题。
Closure nested = {
foo () //will throw missingMethod exception
}
Closure root = {
foo () //prints 'missing foo []'
inline_nested {
foo () //prints 'missing foo []'
}
nested ()
}
builder.execute (root)
// ...
class MyBuilder {
void execute (Closure closure) {
def clone = closure.clone()
clone.delegate = this
clone()
}
def missingMethod (String name, args) {
println "missing ${name} ${args}"
}
}
有什么办法可以为嵌套闭包设置委托属性吗?
答案 0 :(得分:2)
如果你想编写一个构建器,你应该考虑扩展BuilderSupport,而不是从头开始编写它。它负责将每个方法调用委托给正确的对象。
答案 1 :(得分:1)
我不会,你不能。你可能不需要它。
第一。您是关闭的所有者或委托人。如果您直接调用其他地方定义的闭包,则在没有您的构建器帮助的情况下解析该调用
第二。你真的需要nested()
吗?我相信您可以轻松使用execute nested
代替
这是我的意思的一个例子
def nested2 = {
someMethodAtNested2 '3'
println "nested2! - $it"
}
def nested1 = {arg1,arg2->
someMethodAtNested1 '2'
println "nested1! - $arg1"
include nested2, arg2
}
def root = {
someMethodAtRoot '1'
println "root!"
include nested1, 'param1', 'param2'
}
new FooBuilder().build root
class FooBuilder {
void build(Closure closure) {
include closure
}
def include(Closure closure, ...args) {
def clone = closure.clone()
clone.delegate = this
clone.resolveStrategy = Closure.DELEGATE_FIRST
clone(*args)
}
def methodMissing(String name, args) {
println "missing ${name} ${args}"
}
}
作为旁注,我不认为建设者的支持是可行的方式。它可能对在java中创建构建器很有用。但纯粹的groovy要容易得多。至少对于中小型复杂的建设者(从未写过一个非常大的建筑商) 你确实需要了解groovy方法调度过程的一些知识