2011-07-11 2 views
3

J'ai besoin d'aide avec l'une des fonctionnalités Groovy 1.8 DSL.Groovy 1.8 a b c style

Tenir compte this cas de test:

/** 
* For odd number of elements, treat the last element as a call to a getter 
* 
* case   a b c 
* equivalent  a(b).getC() 
*/ 
void testTrailingElementAsGetter() { 
    def drank = false 
    def more = 'more' 
    def drink = { String s -> [milk: { drank = true }()] } 

    def d = drink more milk 

    assert drank 
} 

Si je change [milk: { drank = true }()] à [foo: { drank = true }()], le cas de test passe encore. Cela pourrait-il être un bug dans la nouvelle implémentation ou est-ce que je manque quelque chose dans la syntaxe de Groovy?

EDIT - RESOLU: @han et @Gareth Davis ont tous deux fourni les bons indices. Voici quelques détails pour comprendre ce test:

groovy:000> more = 'more' 
    ===> more 
    groovy:000> drank = false 
    ===> false 
    groovy:000> drink = { String s -> [milk: { drank = true }()] } 
    ===> [email protected] 
[A] groovy:000> drink more 
    ===> {milk=true}  
[B] groovy:000> drank 
    ===> true   
    groovy:000> drink more milk 
    ===> true 
    groovy:000> drink more water 
    ===> null 

ligne [A] retourne une carte comme @han souligné. Dans la ligne [B], drank est déjà true, en raison de la fermeture d'exécution immédiatement après la création (comme @Gareth Davis a souligné), similaire à la JavaScript module pattern. Je ne pense pas que ce "test" est la meilleure façon de présenter cette fonctionnalité - l'effet secondaire sur drank est trompeur.

Répondre

1
groovy:000> drank =false 
===> false 
groovy:000> d = {x -> [y: {drank=true}()]} 
===> [email protected] 
groovy:000> drank 
===> false 
groovy:000> d 2 
===> {y=true} 
groovy:000> drank 
===> true 

x sur les premiers jeux de Invoke bu true devient alors juste une carte {y: true}

tout à fait un comportement déconcertant vraiment

de ce que nous pouvons voir il y a beaucoup façons de synthétiser un DSL à partir de la nouvelle syntaxe - cartes de déréférencement de clés - fermeture et appel - classe et méthode

be bary

2

le problème est:

def drink = { String s -> [milk: { drank = true }()] } 

changement:

def drink = { String s -> [milk: { drank = true }] } 

La fuite parens où appeler effectivement la fermeture sur la création plutôt que sur l'exécution de la LIS.

def d = drink more milk 

// d is actually a closure not a boolean you would need to invoke it in order to get the required side effect of setting drank. 
d.call() 
Questions connexes