Groovy DSL - 用于创建对象的快捷方式

时间:2012-09-19 18:44:32

标签: groovy dsl

Groovy中有一种方法可以替换下面的代码:

Task a = new Task('a')
Process p = new Process('p')

更简单,例如:

task a
process p

其中taskprocess可以是创建对象并将其返回的方法调用,也可以将其添加到脚本Map中。

我目前遇到的主要问题是我无法使用a,因为它没有定义。

2 个答案:

答案 0 :(得分:5)

要创建对象并将其命名而不指定给变量,可以使用绑定。创建并保持对闭包绑定的引用,并让实用方法taskprocess将新实例与名称相关联。例如:

def scriptBinding = new Binding()

def task = { String name ->
    scriptBinding[name] = new Task(name)
}
def process = { String name ->
    scriptBinding[name] = new Process(name)
}

def script = {
    task 'a'
    process 'b'

    println a
    println b
}
script.binding = scriptBinding
script()

请注意,您必须引用ab,以便将它们解释为字符串而不是未定义的变量。如果您想省略引号,可以使用自定义Binding对象来评估未定义的符号作为它们的字符串表示形式,如下所示:

class SymbolAsStringBinding extends Binding {
    Object getVariable(String name) {
        try {
            super.getVariable(name)
        } catch (MissingPropertyException e) {
            name
        }
    }

    boolean hasVariable(String name) {
        true
    }
}

通过添加,您可以将脚本编写为:

def script = {
    task a
    process b

    println a
    println b
}

答案 1 :(得分:1)

试试这个:

class Task {
    String name
    Task(name) { this.name = name }
    String toString() { "task: $name".toString() }
}

def propertyMissing(String name) { this.getBinding()[name] = name }

def task(name) { this.getBinding()[name]  = new Task(name) }

task a
println a

这会产生:

 task: a

基本上是在你到达

task a

语句propertyMissing()将绑定一个名为a的变量,其内容为其名称。 稍后,task()函数将使用新任务替换绑定中的变量a,并将名称替换为缺失的变量a