2011-07-11 28 views
3

我需要一個Groovy 1.8 DSL功能的幫助。Groovy 1.8 a b c風格

考慮this測試用例:

/** 
* 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 
} 

如果我改變[milk: { drank = true }()][foo: { drank = true }()],測試用例依然通過。這可能是新實現中的一個錯誤,或者我錯過了Groovy語法中的某些東西?

編輯 - 已解決:@han和@Gareth Davis都發布了正確的線索。這裏有一些更多的細節來了解一下測試:

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 

線爲@han指出[A]返回地圖。由於在創建後立即執行了封閉(如@Gareth Davis指出的),因此在行[B],drank已經是true,類似於JavaScript module pattern。我不認爲這個「測試」是展示這種功能的最佳方式 - drank的副作用是不正確的。

回答

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喝真就變成只是一個地圖{Y:真正}

從這個相當令人費解的行爲真的

我們可以看到 有很多從新的1.8語法合成DSL的方法 - 密鑰解引用映射 - 封閉和呼叫 - 類和方法

be bary

2

的問題是:

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

變化:

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

尾隨其中的括號實際上,呼籲創造,而不是上運行的DSL關閉。在第一次調用集合

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() 
相關問題