#groovy #jenkins-groovy
#groovy #дженкинс-заводной
Вопрос:
Ниже приведен код Jenkins groovy в скриптовом конвейере, который мы используем для передачи методов
def dict = [:]
def register(String x, Closure y){ dict[x]=y }
мы говорим, register('a', this.amp;foo)
чтобы передать метод, register()
принимающий замыкания в качестве второго аргумента
где foo()
находится метод
def foo(parm){
// do something with parm
}
где parm
возможным значением является ‘a’
Каким должен быть тип второго аргумента register
метода, чтобы избежать передачи this.amp;foo
и скорее вызвать register('a', foo)
?
Ответ №1:
Если вы хотите вызвать, register('a', foo)
тогда foo
должно быть замыкание, например
def foo = {
// closure body here
}
вместо
def foo() {
// method body here
}
Конструкция this.amp;foo
называется оператором указателя на метод и используется для преобразования метода в замыкание. Если foo
должен оставаться метод, то вы не можете избежать this.amp;foo
operator . Groovy не поддерживает передачу методов как foo
. С другой стороны, ваш register
метод ожидает закрытия в качестве второго параметра, поэтому необходимо указать параметры:
- определить
foo
как замыкание - или преобразовать
foo
метод в замыкание с помощьюthis.amp;foo
оператора
Комментарии:
1. как вызвать конкретное закрытие? этот синтаксис не работает
dict['a']('a')
. В нашем сценарии этоdef variable = 'a'
и мы хотим сделатьdict[var](var)
2. на самом деле это
def foo(parm){}
метод в запросе. Запрос отредактирован3. Я ожидаю, что второй параметр
register
получит тип метода, но не тип закрытия4. @overexchange Groovy не поддерживает передачу методов в качестве параметров функциям. Вот почему был введен параметр указателя метода, потому что замыкание в Groovy является эквивалентом метода (в упрощении, конечно).
5. Каждый скрипт Groovy компилируется в класс, который расширяется
groovy.lang.Script
. Тело скрипта перемещается вScript.run()
метод, поэтому каждая переменная, используемая в скрипте, является локальной переменнойScript.run()
метода.@Field
Аннотация делает переменную полем класса, а не локальной переменной. Каждый метод, определенный в скрипте, компилируется как метод класса, например,register()
метод являетсяScript.register()
методом. В этом методе вы пытаетесь получить доступpushMethodLookUp
, поэтому, если вы хотите разделить его междуregister
методом и телом узла, вам нужно перенести его в поле класса.
Ответ №2:
Ссылку на функцию можно получить, используя символ «amp;»; например, это.amp;bar
def foo(Closure c) {
c("foo")
}
def bar(arg) {
println "Hellow World: ${arg}"
}
println(foo(this.amp;bar))
Output:
Hellow World: foo