Como é Gant capaz de alvos de referência por seus nomes, e não obter uma exceção propriedade faltando?
-
19-09-2019 - |
Pergunta
No código apresentado aqui: Gant arquivo , há o seguinte código:
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)
Estou interessado em saber como ele é capaz de escrever setDefaultTarget(dist)
, e não receber uma exceção sobre dist
como uma propriedade ausente. É este trecho avaliada no contexto de algum objeto, e as metas de criar variáveis ??de instância?
Solução
Existem dois itens que você precisa considerar, a ligação do roteiro, e como um alvo é declarada.
Primeiro, há a ligação. Um script Groovy é um pouco diferente de uma classe Groovy / Java. scripts do Groovy permitem variáveis ??não ligados. Significado quando você compilar o script a necessidade variável não ser declarado. Quando o compilador vê uma dessas referências de variáveis ??não declaradas, ele irá converter o refrence para a variável sob as tampas a uma chamada para binding.getVariable (nome da variável) (ou algo por aí). Assim, a última linha do script é funcionalmente equivilant para
setDefaultTarget(binding.getVariable('dist'))
Em segundo lugar, há a é a declaração do alvo. Quando o alvo é declarado o compilador Groovy é realmente vendo uma chamada de método: alvo (args Mapa, fechamento Encerramento) (ou por aí). Quando este método é executado que examina os args, extrai o nome do alvo, e armazena alguma referência enrolada para o fecho por esse nome na ligao. Um appropximation seria ..
target(Map args, Closure closure) {
binding.setVarialbe(
args.keySet().iterator().next(),
gantClosureWrapping(args, closure))
}
Claro que o código acima é uma aproximação e não o código gant real.
Então, em essência ...
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')