I\'m trying to generate a closure from a string. The code inside the closure references a DSL function build(). The errors I\'m getting imply that Groovy is trying to exec
If you are evaluating the String from your DSL configuration script, you do not need to create a GroovyShell object.
Your script will be run as a subclass of Script
which provides a convenience method for evaluating a string with the current binding.
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
So in this case, you'd just need to call evaluate('{ -> build("my job") }')
.
What about returning the closure from the script?
Eval.me("return { build('my job') } ")
What do you intend using that L:
? Returning a map? If is that so, you can use square brackets:
groovy:000> a = Eval.me("[L: { build('test for') }]")
===> {L=Script1$_run_closure1@958d49}
groovy:000> a.L
===> Script1$_run_closure1@958d49
Consider the example below. The key is to specify, explicitly, a closure without parameters.
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()
In addition to Michael Easter's answer, you could also pass the script's binding through to the GroovyShell
def build = { ->
"BUILD $it"
}
def shell = new GroovyShell( this.binding )
def c = shell.evaluate( "{ -> build( 'tim_yates' ) }" )
c()