Двойная замена переменной Groovy

Я хочу выполнить двойную замену.

При печати:

def y    = "\${x}"
def x    = "world"
def z    = "Hello ${y}"
println z

Он печатает:

Hello ${x}

Когда мне нужно было напечатать Hello World, я попытался выполнить двойную оценку ${${}}, приведя ее к org.codehaus.groovy.runtime.GStringImpl и в отчаянии ${y.toStrin()}

Изменить:

Чтобы быть более ясным, я имею в виду это, но в Groovy:

(Почему я это делаю?: потому что у нас есть несколько текстовых файлов, которые нам нужно оценить с помощью переменных groovy; переменных много и в разных частях кода разные, поэтому я хотел бы иметь решение, работающее во всех случаях, чтобы не привязывать каждый раз каждую переменную, не добавляя много строк кода)


person GalloCedrone    schedule 11.01.2019    source источник


Ответы (2)


Итак, с тем, что у вас есть, вы избегаете $, поэтому он просто интерпретируется как строка.

Для того, что вы хотите сделать, я бы посмотрел на механизмы шаблонов Groovys: http://docs.groovy-lang.org/docs/next/html/documentation/template-engines.html

Прочитав ваш комментарий, я поиграл с несколькими идеями и придумал этот надуманный ответ, который, вероятно, также не совсем то, что вы ищете:

import groovy.lang.GroovyShell

class test{
    String x = "world"
    String y = "\${x}"
    void function(){
        GroovyShell shell = new GroovyShell();
        Closure c = shell.evaluate("""{->"Hello $y"}""")
        c.delegate = this
        c.resolveStrategry = Closure.DELEGATE_FIRST
        String z = c.call()
        println z
    }
}

new test().function()

Но это было самое близкое, что я мог придумать, и может привести вас к чему-то...

person virtualdogbert    schedule 11.01.2019
comment
Если я не ошибаюсь, это подтолкнет меня к использованию привязок, это не то, что я ищу, поскольку мне потребуется много кода для каждого случая. Я искал решение так же просто, как ${${text}} - person GalloCedrone; 12.01.2019
comment
Я обновил свой ответ другой идеей, хотя это немного надумано - person virtualdogbert; 12.01.2019
comment
Спасибо, я попробовал это, и это было то, что я искал. Он выполняет двойную (и тройную) замену и может использоваться как отдельная функция, передавая y в качестве параметра! - person GalloCedrone; 14.01.2019

Если я правильно понимаю, вы читаете y откуда-то еще. Итак, вы хотите оценить y как GString после загрузки y, а затем x. groovy.util.Eval сделает это для простых случаев. В этом случае у вас есть только одна переменная привязки: x.

def y = '${x}'
def x = 'world'

def script = "Hello ${y}"
def z = Eval.me('x', x, '"' + script + '".toString()') // create a new GString expression from the string value of "script" and evaluate it to interpolate the value of "x"
println z
person emilles    schedule 12.01.2019
comment
Это будет простая замена, а не двойная замена! - person GalloCedrone; 12.01.2019
comment
Это печатает Hello world. Разве это не тот результат, которого вы добиваетесь? - person emilles; 12.01.2019
comment
Также println "Hello world" делает, но я не искал такого решения. Меня интересовал способ реализации двойной замены, что-то вроде этого заголовка unix.stackexchange.com/questions/68042/, обновлю вопрос :) - person GalloCedrone; 12.01.2019
comment
Если вы намерены загрузить содержимое y откуда-то еще, то вы хотите, чтобы его текст рассматривался как GString, я думаю, что Eval сделает это. - person emilles; 12.01.2019
comment
Спасибо, попробую! - person GalloCedrone; 12.01.2019