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

Groovy DSL-创建对象的快捷方式,groovy,dsl,Groovy,Dsl,Groovy中是否有一种方法可以替换以下代码: Task a = new Task('a') Process p = new Process('p') 用更简单的方法,比如: task a process p 其中,task和process可以是创建对象并将其返回或添加到脚本映射的方法调用 我目前面临的主要问题是,我无法使用a,因为它没有定义。要创建对象并命名它们而不指定变量,可以使用绑定。创建并保留对a闭包绑定的引用,并使用实用程序方法task和process将新实例与名称关联。例如: d

Groovy中是否有一种方法可以替换以下代码:

Task a = new Task('a')
Process p = new Process('p')
用更简单的方法,比如:

task a
process p
其中,
task
process
可以是创建对象并将其返回或添加到脚本映射的方法调用


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

要创建对象并命名它们而不指定变量,可以使用绑定。创建并保留对a闭包绑定的引用,并使用实用程序方法
task
process
将新实例与名称关联。例如:

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()
请注意,必须引用
a
b
,以便将它们解释为字符串,而不是未定义的变量。如果要省略引号,可以使用自定义绑定对象,该对象将未定义符号作为其字符串表示形式进行求值,如下所示:

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
}
试试这个:

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

,您还可以使用
def propertyMissing(String p){p}
来避免自定义绑定,并且已经将变量解析为字符串