Можно ли получить имя переменной в Groovy? - PullRequest
3 голосов
/ 02 апреля 2019

Хотелось бы узнать, возможно ли получить имя переменной.

Например, если у меня есть метод:

def printSomething(def something){
//instead of having the literal String something, I want to be able to use the name of the variable that was passed
println('something is: ' + something)
}

Если я вызываю этот метод следующим образом:

 def ordinary = 58
 printSomething(ordinary)

Я хочу получить:

ordinary is 58

С другой стороны, если я вызову этот метод следующим образом:

def extraOrdinary = 67
printSomething(extraOrdinary)

Я хочу получить:

extraOrdinary is 67

Редактировать

Мне нужно имя переменной, потому что у меня есть этот фрагмент кода, который выполняется перед каждым TestSuite в Katalon Studio , в основном это дает вам гибкость передачи GlobalVariables с помощью файла katalon.features,Идея от: kazurayam / KatalonPropertiesDemo

  @BeforeTestSuite
    def sampleBeforeTestSuite(TestSuiteContext testSuiteContext) {
        KatalonProperties props = new KatalonProperties()
        // get appropriate value for GlobalVariable.hostname loaded from katalon.properties files
        WebUI.comment(">>> GlobalVariable.G_Url default value: \'${GlobalVariable.G_Url}\'");

//gets the internal value of GlobalVariable.G_Url, if it's empty then use the one from katalon.features file
            String preferedHostname = props.getProperty('GlobalVariable.G_Url')
            if (preferedHostname != null) {
                GlobalVariable.G_Url = preferedHostname;
                WebUI.comment(">>> GlobalVariable.G_Url new value: \'${preferedHostname}\'");
            } else {
                WebUI.comment(">>> GlobalVariable.G_Url stays unchanged");
            }
 //doing the same for other variables is a lot of duplicate code
        }

Теперь это обрабатывает только 1 значение переменной, если я делаю это, скажем, для 20 переменных, то есть много повторяющегося кода, поэтому яхотел создать вспомогательную функцию:

def setProperty(KatalonProperties props, GlobalVariable var){
   WebUI.comment(">>> " + var.getName()" + default value: \'${var}\'");

//gets the internal value of var, if it's null then use the one from katalon.features file
            GlobalVariable preferedVar = props.getProperty(var.getName())
            if (preferedVar != null) {
                var = preferedVar;
                WebUI.comment(">>> " + var.getName() + " new value: \'${preferedVar}\'");
            } else {
                WebUI.comment(">>> " + var.getName() + " stays unchanged");
            }
}

Здесь я просто поместил var.getName (), чтобы объяснить, что я ищу, это просто метод, который я предполагаю.

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

Да, это возможно с помощью преобразований AST или макросов (Groovy 2.5+).

В настоящее время у меня нет подходящей среды разработки, но вот несколько советов:

Не то чтобы оба варианта не были тривиальными, я бы не советовал новичку в Groovy, и вам придется провести некоторое исследование. Если я правильно помню, для надежной работы любой из этих опций требуется отдельная сборка / проект из вызывающего кода. Также любой из них может дать вам неясные и трудные для отладки ошибки времени компиляции, например, когда ваш код ожидает переменную в качестве параметра, но передается литерал или вызов метода. Итак: там будут драконы. Это сказанное: я много работал с этими вещами, и они могут быть действительно забавными;)

Groovy Документация для макросов

Если вы используете Groovy 2.5+, вы можете использовать макросы. Для вашего варианта использования взгляните на раздел @Macro methods. Ваш метод будет иметь два параметра: MacroContext macroContext, MethodCallExpression callExpression последний является интересным. MethodCallExpression имеет getArguments() -методы, которые позволяют получить доступ к узлам дерева абстрактного синтаксиса, которые были переданы методу в качестве параметра. В вашем случае это должно быть VariableExpression , которое имеет метод getName(), чтобы дать вам имя, которое вы ищете.

Разработка преобразований AST

Это более сложная версия. Вы все равно получите тот же VariableExpression, что и с макро-методом, но это будет утомительно, поскольку вам придется самостоятельно определить правильный MethodCallExpression. Вы начинаете с ClassNode и сами продвигаетесь к VariableExpression. Я бы порекомендовал использовать локальное преобразование и создать аннотацию. Но определение правильного MethodCallExpression не тривиально.

0 голосов
/ 02 апреля 2019

нет. это невозможно.

однако подумайте об использовании карты в качестве параметра и передаче имени и значения свойства:

def printSomething(Map m){
    println m
}

printSomething(ordinary:58)
printSomething(extraOrdinary:67)
printSomething(ordinary:11,extraOrdinary:22)

это выдаст

[ordinary:58]
[extraOrdinary:67]
[ordinary:11, extraOrdinary:22]
...