我需要有关 Groovy 1.8 DSL 功能之一的帮助。
考虑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: { drrank = true }()]
更改为 [foo: { drrank = true }()]
,测试用例仍然通过。这可能是新实现中的错误,还是我在 Groovy 语法中遗漏了某些内容?
编辑 - 已解决:@han 和 @Gareth Davis 都发布了正确的线索。以下是了解此测试的更多详细信息:
groovy:000> more = 'more'
===> more
groovy:000> drank = false
===> false
groovy:000> drink = { String s -> [milk: { drank = true }()] }
===> groovysh_evaluate$_run_closure1@20c87621
[A] groovy:000> drink more
===> {milk=true}
[B] groovy:000> drank
===> true
groovy:000> drink more milk
===> true
groovy:000> drink more water
===> null
行[A]
返回一个 map ,正如@han指出的那样。在 [B]
行中,drank
已经是 true
,因为闭包在创建后立即执行(正如@Gareth Davis 指出的那样),类似到JavaScript module pattern 。我不认为这个“测试”是展示此功能的最佳方式 - drank
的副作用是误导性的。
最佳答案
问题出在:
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()
关于Groovy 1.8 a b c 风格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6646811/