Что делает Groovy компилятор из gradle зависит от синтаксиса - PullRequest
1 голос
/ 18 мая 2019

Я понимаю, что DSL

task doTask { logger.info "some text" }

на самом деле вызовет задачу метода (String, Closure) для объекта делегата Project.Это более или менее короткая рука для

task("doTaks", {logger.info("some text")})

Все хорошо.Но все усложняется, когда я пытаюсь понять синтаксис Gradle DSL, который я видел в сторонних скриптах сборки:

task doTask (dependsOn: 'otherTask'){logger.info "some text"}

Я полагаю, что groovy создаст карту из (depenon: 'otherTask'), ичто каким-то образом будет вызван метод Project

task(Map args, String name, Closure config)

.Но как эти дополнительные круглые скобки вступают в игру, почему они необходимы, как Groovy выясняет, чего мы хотим здесь?Синтаксис выглядит совершенно нелогичным для меня с минимальными навыками.Я бы никогда не подумал, что мне нужно сделать так, чтобы это работало.

Итак, вот в чем вопрос: как groovy выясняет, что делать с этой командой:

task doTask (dependsOn: 'otherTask'){ // some code }

1 Ответ

1 голос
/ 19 мая 2019

Вы можете вызывать Groovy методы, используя один из следующих синтаксисов:

  1. Все аргументы должны быть запятыми в скобках:

    method(arg1, arg2, ..., argN, argClosure)
    
  2. Все аргументы должны быть разделены запятой без скобок:

    method arg1, arg2, ..., argN, argClosure
    
  3. Если последний аргумент является закрытием, все предыдущие аргументы должны быть разделены запятой в скобках, а блок кода (в фигурных скобках {...}) после закрывающей скобки будет интерпретирован как последний Closure аргумент argClosure:

    method(arg1, arg2, ..., argN) { ... }
    

    Если вы НЕ хотите, чтобы блок кода в фигурных скобках интерпретировался как аргумент Closure для предыдущего вызова метода; затем завершите вызов метода точкой с запятой:

    // Because of `;` following { ... } is not a Closure argument for `method`
    method(arg1, arg2, ..., argN); { ... }
    
  4. Метод, который принимает в качестве аргумента один Map или Map и замыкание, может быть вызван с использованием синтаксиса named parameters ; который преобразует каждый именованный аргумент в запись на карте, а последний аргумент будет замыканием. Это создаст следующие интуитивные синтаксические варианты:

    method(name1: arg1, name2: arg2, ..., nameN: argN, argClosure)
    method name1: arg1, name2: arg2, ..., nameN: argN, argClosure
    method(name1: arg1, name2: arg2, ..., nameN: argN) { ... }
    

Groovy предоставляет тонны синтаксического сахара, так что можно найти другие интуитивные варианты; но это дает вам представление о том, как Groovy обрабатывает Closure аргументов.

Ниже приведена рабочая демонстрация этих различных способов выполнения вызова метода:

import java.time.LocalDateTime

def handleWithClosure(data1, data2, closure) {
    closure("$data1. $data2")
}

def logger = { println "${LocalDateTime.now()} - $it" }
handleWithClosure(1, 'All within parenthesis', logger)
handleWithClosure 2, 'All without parenthesis', logger
handleWithClosure(3, 'List of arguments within parenthesis and closure outside') { logger(it) }

def handleMapWithClosure(map, closure) {
    handleWithClosure(map['num'], "[Named Arguments/Map based] ${map['msg']}", closure)
}

handleMapWithClosure(msg: 'All within parenthesis', num: 1, logger)
handleMapWithClosure msg: 'All without parenthesis', num: 2, logger
handleMapWithClosure(msg: 'List of arguments within parenthesis and closure outside', num: 3) { logger(it) }

Запустив его, вы можете увидеть, как он обрабатывает все эти синтаксические опции.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...