Groovy 1.8 в стиле a b c

Мне нужна помощь с одной из функций Groovy 1.8 DSL.

Рассмотрим этот тест кейс:

/**
 * 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 }()] }
    ===> 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] возвращает карту, как указал @han. В строке [B] drank уже true из-за закрытия, выполняемого сразу после создания (как указал @Gareth Davis), аналогично Шаблон модуля JavaScript. Я не думаю, что этот «тест» — лучший способ продемонстрировать эту функцию — побочный эффект drank вводит в заблуждение.


person Binil Thomas    schedule 11.07.2011    source источник


Ответы (2)


groovy:000> drank =false
===> false
groovy:000> d = {x -> [y: {drank=true}()]}
===> groovysh_evaluate$_run_closure1@170b819
groovy:000> drank
===> false
groovy:000> d 2  
===> {y=true}
groovy:000> drank
===> true

x при первом вызове устанавливает значение true для выпитого, а затем становится просто картой {y : true}

довольно загадочное поведение на самом деле

из этого мы видим, что есть много способов синтезировать DSL из нового синтаксиса 1.8 - карты разыменования ключей - закрытие и вызов - класс и метод

быть бари

person han    schedule 11.07.2011

проблема в:

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()
person Gareth Davis    schedule 11.07.2011