2016-02-22 3 views
1

Я пытаюсь создать небольшую DSL, но я не понимаю следующий порядок выполнения.Закрытие Groovy - непонятный запрос на вызов

Маршрутизатор DSL имеет заявление как summarize tests of 'me'

мой Groovy скрипт для интерпретации:

def tests = { 
    [of: { who -> 
      println "IN CLOSURE" 
      "HALLO" // dummy value for testing 
     }] 
} 

def summarize(Closure c) { 
    println "SUMMARIZE - CALL CLOSURE" 
    def f = c() 
    println "SUMMARIZE - CALL CLOSURE" 
    println "RESULT $f" 
    f 
} 

и мой сценарий абонент имеет

def g = summarize tests of 'me' 
println g 

Выход

SUMMARIZE - CALL CLOSURE 
SUMMARIZE - CALL CLOSURE 
RESULT [of:[email protected]1802] 
IN CLOSURE 
HALLO 

На самом деле я хочу получить результат закрытия tests в методе summarize, но кажется, что там еще не было вызвано внутреннее закрытие - какая магия происходит после этого, чтобы сценарий имел правильный результат?

Может кто-нибудь объяснить мне, почему порядок исполнения? И как я могу получить HALLO уже в методе summarize?

Спасибо за любую помощь

ответ

2

В вашем примере, test является замыкание, которое возвращает карту. Если вы звоните test() вы получите [of: {...}]

Это то, что вы видите в вашей консоли, при печати f. Для заводной

summarize tests of 'me' 

эквивалентно

summarize(tests).of('me') 

ваша summarize(tests) выполняют tests(), которая возвращает карту [of:{..}]. После этого вы выполняете map.of, которые возвращают закрытие, а затем вы вызываете это закрытие с параметрами me.

Есть разные варианты получения того, что вы хотите, но это зависит от полного «dsl», который вы хотите реализовать, а не только этой специальной утилиты. Самый простой способ, которым я думаю, только с этим предложением, возвращается промежуточный объект, который срабатывает при вызове `из ':

def summarize(t) { 
    return [ 
    of: { who -> 
     def f = t().of(who) 
     println f 
    } 
    ] 
} 
+0

спасибо за разъяснение - есть то любой способ структурировать это, чтобы получить результат закрытия уже доступно в 'summaryize'? –

+0

Я добавил пример того, что можно сделать, но, честно говоря, это уродливо. Вы должны более точно определить, что вам нужно в DSL ;-) –

+0

еще раз спасибо - идея состоит в том, чтобы фильтровать/отображать результаты. 'tests 'me'' - это закрытие, которое возвращает набор результатов (полная информация об объекте). «Суммирование» будет тогда, например, только верните заголовок результатов. –