通过Groovy中的嵌套闭包传递委托

时间:2011-05-12 05:45:32

标签: groovy metaprogramming expandometaclass

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

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

2 个答案:

答案 0 :(得分:2)

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

Here's an example of a JSON builder I wrote扩展此课程。

答案 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方法调度过程的一些知识