需要Groovy语法帮助从String生成Closure

时间:2013-06-23 21:59:21

标签: groovy dsl evaluate

我正在尝试从字符串生成闭包。闭包内的代码引用了DSL函数build()。我得到的错误暗示Groovy正在尝试执行关闭而不是仅仅声明它。这个的正确语法是什么?以下是我已经尝试过的一些结构。

sh = new GroovyShell() 
cl = sh.evaluate( '{ build("my job") }' } 
=> Ambiguous expression could be either a parameterless closure expression or an isolated open code block;

sh = new GroovyShell() 
cl = sh.evaluate( 'L: { build("my job") }' } 
=> No signature of method: Script1.build() is applicable ...

cl = Eval.me( 'L: { build("my job") }' } 
=> No signature of method: Script1.build() is applicable ...

cl = Eval.me( 'L: { com.flow.FlowDelegate.build("my job") }' } 
=> No such property: com for class: Script1

我想要遵循的例子来自: Load closure code from string in Groovy

4 个答案:

答案 0 :(得分:1)

如何从脚本中返回闭包?

Eval.me("return { build('my job') } ")

您打算如何使用L:?回到地图?如果是这样,你可以使用方括号:

groovy:000> a = Eval.me("[L: { build('test for') }]")
===> {L=Script1$_run_closure1@958d49}
groovy:000> a.L
===> Script1$_run_closure1@958d49

答案 1 :(得分:1)

考虑以下示例。关键是明确指定不带参数的闭包。

def build = { def jobName ->
    println "executing ${jobName}"
}

// we initialize the shell to complete the example
def sh = new GroovyShell()
sh.setVariable("build", build)

// note "->" to specify the closure
def cl = sh.evaluate(' { -> build("my job") }')

println cl.class
cl.call()

答案 2 :(得分:0)

除了Michael Easter's answer之外,您还可以将脚本的绑定传递给GroovyShell

def build = { ->
  "BUILD $it"
}

def shell = new GroovyShell( this.binding )
def c = shell.evaluate( "{ -> build( 'tim_yates' ) }" )

c()

答案 3 :(得分:0)

如果您正在从DSL配置脚本中评估String,则无需创建GroovyShell对象。

您的脚本将作为Script的子类运行,它为使用当前绑定评估字符串提供了便利方法。

public Object evaluate(String expression)
            throws CompilationFailedException

A helper method to allow the dynamic evaluation of groovy expressions using this scripts binding as the variable scope

因此,在这种情况下,您只需要拨打evaluate('{ -> build("my job") }')