Come è Gant in grado di fare riferimento a obiettivi con il loro nome, e non ottenere un'eccezione immobile manca?

StackOverflow https://stackoverflow.com/questions/2231972

Domanda

Nel codice qui presentata: Gant il file , v'è il seguente codice:

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)

Mi interessa come è in grado di scrivere setDefaultTarget(dist), e non riceve un'eccezione circa dist come una proprietà mancante. E 'questo frammento valutato nel contesto di un oggetto, e gli obiettivi di creare variabili di istanza?

È stato utile?

Soluzione

Ci sono due elementi da tenere in considerazione, il legame dello script, e come un obiettivo viene dichiarato.

In primo luogo c'è il legame. Uno script Groovy è un po 'diverso da una classe Groovy / Java. Groovy script consentono per le variabili non legati. Significato quando si compila lo script non deve essere dichiarata la variabile. Quando il compilatore vede uno di questi riferimenti variabile non dichiarata, che convertirà il refrence alla variabile sotto le coperte per una chiamata a binding.getVariable (nome della variabile) (o qualcosa giù di lì). Quindi l'ultima riga dello script è funzionalmente l'equivalente di

setDefaultTarget(binding.getVariable('dist'))

In secondo luogo v'è la è la dichiarazione del bersaglio. Quando il bersaglio viene dichiarato il compilatore Groovy è in realtà vedendo una chiamata di metodo: bersaglio (Mappa args, Chiusura) (o giù di lì). Quando questo metodo esegue esamina i args, estrae il nome della destinazione, e memorizza qualche riferimento avvolto alla chiusura con quel nome nel legame. Un appropximation sarebbe ..

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

Naturalmente il codice di cui sopra è un'approssimazione e non il vero e proprio codice di Gant.

Quindi, in sostanza ...

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')
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top