2

我正在创建一个接受 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}"
  }
}

有什么方法可以为嵌套闭包设置委托属性?

4

2 回答 2

2

如果你想编写一个构建器,你应该考虑扩展BuilderSupport而不是自己从头开始编写。它负责将每个方法调用委托给正确的对象。

这是我通过扩展此类编写的 JSON 构建器的示例。

于 2011-05-12T08:48:49.933 回答
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 方法调度过程的知识

于 2011-05-14T00:15:11.207 回答