2013-06-23 8 views
2

Я пытаюсь создать замыкание из строки. Код внутри замыкания ссылается на функцию сборки DSL(). Ошибки, которые я получаю, подразумевают, что Groovy пытается выполнить закрытие, а не просто объявлять его. Каков правильный синтаксис для этого? Вот некоторые из конструкций, которые я уже пробовал.Необходимость помощи синтаксиса 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

ответ

0

В дополнение к Michael Easter's answer, можно также передать сценария привязки через к GroovyShell

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

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

c() 
+0

Является ли groovy оболочкой потокобезопасным? Могу ли я создать только одно и повторное использование в граале? – raffian

1

Что о возвращении закрытие из сценария?

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

Что вы намерены использовать, что L:? Возвращение карты? Если это так, вы можете использовать квадратные скобки:

groovy:000> a = Eval.me("[L: { build('test for') }]") 
===> {[email protected]} 
groovy:000> a.L 
===> [email protected] 
+0

Я думаю, что L: добавлено в соответствии с предложением Groovy console «Неоднозначное выражение может быть либо беззазорным закрывающим выражением, либо изолированным открытым блоком кода», «solution: Добавить явный список параметров закрытия, например {it -> .. .} или заставить его рассматривать как открытый блок, указав ему метку, например L: {...} " –

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() 
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") }').