Groovy 1.8 abc style - PullRequest
       26

Groovy 1.8 abc style

3 голосов
/ 11 июля 2011

Мне нужна помощь с одной из функций 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 ошибочен.

Ответы [ 2 ]

2 голосов
/ 11 июля 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()
1 голос
/ 11 июля 2011
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 при первом вызове устанавливает выпить до истины, а затем становится просто картой {y: true}

довольно странное поведение на самом деле

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

be bary

...