You can perform another closure in the same "context" by setting a "delegate" to close. A closure is not multithreaded (only one delegate at a time), so you will have to clone the closure each time if the closure is shared in a singleton class or static variable.
This is just an idea of code refactoring, it may not work (I have not tested it). You can replace the assignment (=) with calls to the setProperty and DSL methods with "invokeMethod" if you need to dynamically determine the property name or method name in the DSL. (link http://groovy.codehaus.org/api/groovy/lang/Closure.html )
def personClosure = { Person person, varname -> setProperty(varname, { id = person.id firstName = person.firstName lastName = person.lastName }) } def groupMembersClosure = { memberList, memberListVarName, memberVarName -> personClosure.delegate = delegate setProperty(memberListVarName, array { memberList?.person?.sort().each personClosure, memberVarName }) } def builder = new JSONBuilder() def result = builder.build { array { Group.list().each { Group group -> g = { id = group.id name = group.name groupMembersClosure.delegate = delegate groupMembersClosure(group.members, 'members', 'm') groupMembersClosure(group.leaders, 'leaders', 'l') } } } }
source share