[英]Groovy evaluate Strings using DSL while in a Groovy closure
這類似於從字符串生成Closure的Need Groovy語法幫助,但稍微復雜一點:
我正在使用不受控制的復雜DSL(特別是Jenkins Job DSL,但是為了清楚起見,我使用的是假設的DSL),並且我將代碼分解為返回的閉包。 這段代碼中所有不以“ my”開頭的閉包都是假設的DSL:
//scriptContext is a reference to the original script as this is a util class
static def myMethod(def scriptContext) {
//everything here comes from some hypothetical DSL
scriptContext.diningTable() {
....
fruits myCreateFruitsClosure()
....
}
}
static def myCreateFruitsClosure() {
return {
apple('Gala') {
seed("brown")
shape {
funky()
dimpled()
}
}
}
}
以上工作正常。
現在讓我們說,我希望動態指定蘋果的詳細信息,並從某個地方(例如XML)加載一些常規代碼。
我現在有:
// I pass in the script context for the binding
static def myCreateFruitsClosure(def scriptContext) {
return {
apple('Gala') {
// This comes from somewhere in real life:
def code = """seed("blue"); shape { oval() ; cardioid() }"""
def evalWrapper = new GroovyShell(context.binding).evaluate(' { -> ' + code + '}')
evalWrapper()
}
}
}
而且,我得到“方法沒有簽名:Script1.seed()”顯然,由於不使用eval,因此seed()方法確實存在,因為它以前可以工作,所以我的上下文/范圍是錯誤的。
我試過了:
所有這些都會產生略有不同的錯誤。 正確的方法是什么?
最終, 我通過以下方式獲得了這項工作 :
結果如下:
static def myCreateFruitsClosure() {
return {
apple {
def code = """
L:{
self.seed("blue")
self.shape {
oval()
cardioid()
}
}"""
// sometimes "self: delegate" is appropriate instead of this:
new GroovyShell(new Binding([self: owner])).evaluate(code)
}
}
}
我想這比我嘗試做的要簡單。 請注意“ L:”以強制valuate()將代碼視為開放代碼塊而不是閉包。
如果有人有更好的方法,請告訴我,但這行之有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.