Question

I am trying to implement a mini DSL with Groovy:

def parent(closure){
    def container = new ArrayList<>()
    closure.call(container)
    container
}

def child(element, parent) {
    println "add child$element to parent"
    parent.add(element)
}

parent{ it->
    child(1, it)
    child(2, it)
}

But I want to remove the it parameter to make it looks better, like this:

parent{ 
    child(1)
    child(2)
}

Is it possible to do it this way? Many thanks in advance.

Was it helpful?

Solution

It's not a full solution, only example, but I think, you should do it this way:

class Parent{
    def container = new ArrayList<>()
    def child(element) {
        println "add child$element to parent"
        container.add(element)
    }

    def parent(Closure closure){
        closure.delegate = this
        closure.resolveStrategy = Closure.DELEGATE_FIRST
        closure.call()
        container
    }
}


new Parent().parent {
    child(1) // Here we are trying to resolve child method in our delegate, then owner.
    child(2)
}

Of course, you can remove new Parent in future, it's only quick example, to show you delegate magic.

OTHER TIPS

You can use @Field AST in the script if you do not want to create a whole separate class for it:

import groovy.transform.Field

@Field ArrayList container = new ArrayList<>()

//or just list
//@Field def container = []

def parent(Closure closure){
    closure.call()
    container
}

def child(element) {
    println "add child$element to parent"
    container << element
}

parent {
    child(1)
    child(2)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top