Как Гант может ссылаться на цели по их именам, а не получать исключение отсутствующего свойства? - PullRequest
1 голос
/ 09 февраля 2010

В представленном здесь коде: Файл Ганта , есть следующий код:

target(dist: 'Create release artefacts') {
        depends(test)
        depends(jar)
}
target(run: 'Run the distributed jar') {
        depends(dist)
        Ant.java(jar: distributedJarPath, fork: 'true')
}

target(hello: 'Hello World') {
        println("Hello World")
}

setDefaultTarget(dist)

Меня интересует, как он может написать setDefaultTarget(dist) и не получить исключение о dist как отсутствующее свойство. Этот фрагмент оценивается в контексте какого-либо объекта, и цели создают переменные экземпляра?

1 Ответ

1 голос
/ 09 февраля 2010

Есть два момента, которые необходимо учитывать: привязка сценария и способ объявления цели.

Сначала идет привязка. Скрипт Groovy немного отличается от класса Groovy / Java. Groovy-скрипты допускают несвязанные переменные. То есть, когда вы компилируете скрипт, переменную не нужно объявлять. Когда компилятор видит одну из этих необъявленных ссылок на переменные, он преобразует ссылку на переменную под обложками в вызове binding.getVariable (имя переменной) (или что-то подобное). Таким образом, последняя строка сценария функционально эквивалентна

setDefaultTarget(binding.getVariable('dist'))

Второе - это объявление цели. Когда цель объявлена, компилятор Groovy фактически видит вызов метода: target (аргументы Map, Closure closure) (или около того). Когда этот метод выполняется, он проверяет аргументы, извлекает имя цели и сохраняет некоторую завернутую ссылку на замыкание по этому имени в привязке. Приближение будет ..

target(Map args, Closure closure) {
  binding.setVarialbe( 
    args.keySet().iterator().next(),
    gantClosureWrapping(args, closure))
}

Конечно, приведенный выше код является приблизительным, а не реальным кодом Ганта.

так по сути ...

target(dist: 'doc') { ... }
// the above adds 'dist' as a variable to the binding

//...

setDefaultTarget(dist)
// dist is unbound, so it is replaced with binding.getVariable('dist')
...