Groovy DSL:如何隐藏闭包参数?

时间:2014-01-07 02:48:37

标签: groovy metaprogramming dsl

我正在尝试使用Groovy实现迷你DSL:

def parent(closure){
    def container = new ArrayList<>()
    closure.call(container)
    container
}

def child(element, parent) {
    println "add child$element to parent"
    parent.add(element)
}

parent{ it->
    child(1, it)
    child(2, it)
}

但我想删除it参数以使其看起来更好,如下所示:

parent{ 
    child(1)
    child(2)
}

有可能这样做吗? 非常感谢提前。

2 个答案:

答案 0 :(得分:3)

这不是一个完整的解决方案,只是一个例子,但我想,你应该这样做:

class Parent{
    def container = new ArrayList<>()
    def child(element) {
        println "add child$element to parent"
        container.add(element)
    }

    def parent(Closure closure){
        closure.delegate = this
        closure.resolveStrategy = Closure.DELEGATE_FIRST
        closure.call()
        container
    }
}


new Parent().parent {
    child(1) // Here we are trying to resolve child method in our delegate, then owner.
    child(2)
}

当然,您可以在将来删除新的Parent,这只是一个快速示例,向您展示委托魔法。

答案 1 :(得分:2)

如果您不想为它创建一个完整的单独类,可以在脚本中使用@Field AST:

import groovy.transform.Field

@Field ArrayList container = new ArrayList<>()

//or just list
//@Field def container = []

def parent(Closure closure){
    closure.call()
    container
}

def child(element) {
    println "add child$element to parent"
    container << element
}

parent {
    child(1)
    child(2)
}