В противном случае Eval.me ищет поле не в том классе, в котором оно находится

Я пытаюсь прочитать значение переменной с разобранным именем:

class GatewayFunctionBuilder{
    private String responseClass
    .....
    String target = 'esponse'
    println "writing r${target}Class"
    println responseClass
    String targetClass = Eval.me("r${target}Class")

Результат:

writing responseClass
MWFtest0A1Response
:application:generateJavaFromTestMwf FAILED

FAILURE: Build failed with an exception.

* Where:
Script 'C:\Users\543829657\workspace\dev.appl.ib.cbl\application\Xml2Java.gradle' line: 53

* What went wrong:
Execution failed for task ':application:generateJavaFromTestMwf'.
> No such property: responseClass for class: Script1

Содержание напечатанных переменных является правильным. Но, похоже, Eval.me ищет поле responseClass не в классе, из которого оно вызывается, а в скрипте задачи Gradle.

Если я передаю этот объект в качестве параметра, он работает:

String targetClass = Eval.x(this, "x.r${target}Class")

Но это не имеет никакой логики, для this также не является полем сценария задачи, но является чем-то, что имеет правильный смысл только для экземпляра этого класса. И даже если этот экземпляр создается в скрипте задачи (как локальная переменная), у него там другое имя.

Я не вижу упоминаний в документации Eval, что он оценивает строку в контексте некоторого "Script1"

1 ответ

Решение

Код для Eval в Groovy 2.4.4 здесь. Мы наблюдаем следующее:

class Eval { ...
public static Object me(final String expression) throws CompilationFailedException {
    return me(null, null, expression);
}

а также:

 public static Object me(final String symbol, final Object object, final String expression) throws CompilationFailedException {
    Binding b = new Binding();
    b.setVariable(symbol, object);
    GroovyShell sh = new GroovyShell(b);
    return sh.evaluate(expression);
}

так что поведение можно воспроизвести в чистом Groovy, без Gradle:

// Eval.me(expression) == Eval.me(null, null, expression)
def symbol = null
def object = null
def responseClass = "hello"
def target = "esponse"
def expression = "r${target}Class"

def b = new Binding();
b.setVariable(symbol, object);
def sh = new GroovyShell(b);
println sh.evaluate(expression);

где ясно, что expression не будет найден в Binding объект.

Другие вопросы по тегам