amsmota amsmota - 4 months ago 9
Groovy Question

What is and what's the use of the Closure "directive"

I see in the docs and in Closure.java references to "directive" with no explanation of whgat it is or what it is for,

public static final int DONE = 1, SKIP = 2;
private int directive;
/**
* @return Returns the directive.
*/
public int getDirective() {
return directive;
}

/**
* @param directive The directive to set.
*/
public void setDirective(int directive) {
this.directive = directive;
}


I also googled it but I found not a single reference to it, except from some tests where it appears

assert directive = DONE


so the only thing I know is that it can be DONE or SKIP.

Is there any "real life" example of this?

Answer

This directive property is used internally from the groovy runtime as a loop break condition in collect operations see groovy.runtime.DefaultGroovyMethods.java in groovy source code:

    public static <T,E> Collection<T> collect(Collection<E> self, Collection<T> collector, @ClosureParams(FirstParam.FirstGenericType.class) Closure<? extends T> transform) {
    for (E item : self) {
        collector.add(transform.call(item));
        if (transform.getDirective() == Closure.DONE) {
            break;
        }
    }
    return collector;
}

It is accessible via the getter and setter getDirective() and setDirective() in groovy runtime and via the directive property of the closure in your script.

DONE is used to stop the collect operation

For example to stop after 5:

(1..10).collect { 
    if (it>= 5) directive = Closure.DONE;
    new Tuple(it, (int)(it/2) )
}

Result: [[1, 0], [2, 1], [3, 1], [4, 2], [5, 2]]

SKIP is not used ... and has no effect on the collect operation (?!)

This feature sounds a bit like a trick for special cases it is probably better to use collection methods like find, findAll etc. if possible

Comments