【问题标题】:Passing delegate through nested closures in Groovy通过 Groovy 中的嵌套闭包传递委托
【发布时间】:2011-05-12 05:45:31
【问题描述】:

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

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

【问题讨论】:

    标签: groovy metaprogramming expandometaclass


    【解决方案1】:

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

    Here's an example of a JSON builder I wrote 通过扩展这个类。

    【讨论】:

      【解决方案2】:

      我不同意,你不能。你可能不需要它。
      第一的。您是闭包的所有者或代表。如果您直接调用在其他地方定义的闭包,则无需您的构建器帮助即可解决该调用。
      第二。你真的需要那个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 方法调度过程的知识

      【讨论】:

      • 你的权利只需要一个特殊的“包含”方法调用就容易多了。
      猜你喜欢
      • 2019-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-20
      相关资源
      最近更新 更多