3

我正在尝试从字符串生成闭包。闭包内的代码引用了一个 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

我试图遵循的示例来自: 从 Groovy 中的字符串加载闭包代码

4

4 回答 4

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
于 2013-06-23T23:38:52.053 回答
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()
于 2013-06-24T10:42:46.327 回答
0

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

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

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

c()
于 2013-06-23T22:34:48.573 回答
0

如果您正在评估 DSL 配置脚本中的字符串,则不需要创建 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") }').

于 2015-08-31T15:43:02.363 回答