Как передавать методы в Jenkins Groovy?

#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