Thursday, February 13, 2014

groovy Closure Types

Different Closure Types :


class ClosureTypes {

    static void main(args){
        new OwnerFirst().run();
        println ""
        new DelegateFirst().run();
        println ""
        new OwnerOnly().run();
        println ""
        new DelegateOnly().run();
    }  
}

class OwnerFirst{
    def x = 30
    def y = 40
    def z = 22;
    def run() {
        def data = [ x: 10, y: 20]
     
        def cl = { y = x + y+z }
        cl.delegate = data
        //OWNER_FIRST - DEFAULT -> variables x,y,z picks from Owner
        cl()
        println "Owner First"
        println "x = "+x+"; y="+y
        println "Data "+data
    }
}

class DelegateFirst{
    def x = 30
    def y = 40
    def z = 29;
    def run() {
        def data = [ x: 10, y: 20 ]
        def cl = { y = x + y }
        cl.delegate = data
        cl.resolveStrategy = Closure.DELEGATE_FIRST
        cl()
        println "Delegate First"
        println "x = "+x+"; y="+y
        println "Data "+data
    }
}

class OwnerOnly{
    def x = 30
    def y = 40
    def z= 50;
    def run() {
        def data = [ x: 10, y: 20]
        def cl = { y = x + y + z}
        //cl = { y = x + y+z} // Throws Exception - No such property: z for class
        cl.delegate = data
        cl.resolveStrategy = Closure.OWNER_ONLY
        cl()
        println "Owner Only"
        println "x = "+x+"; y="+y
        println "Data "+data
    }
}

class DelegateOnly{
    def x = 30
    def y = 40
    //def z = 50

    def run() {
        def data = [ x: 10, y: 20, z: 25 ]
        def cl = { y = x + y  }
        cl = { y = x + y +z }
        cl.delegate = data
        cl.resolveStrategy = Closure.DELEGATE_ONLY
        cl()
        println x
        println y
        println data
    }
}


Prints :
Owner First
x = 30; y=92
Data [x:10, y:20]

Delegate First
x = 30; y=40
Data [x:10, y:30]

Owner Only
x = 30; y=120
Data [x:10, y:20]

30
40
[x:10, y:55, z:25]

Source : http://groovy.codehaus.org/api/groovy/lang/Closure.html

Method Calls in Groovy Closure

Here is the example, to call methods from the Closure, at runTime
class MethodCallsInClosure {

    def call1(){
        println "Call 1";
    }
 
    def call2(){
        println "Call 2";
    }
    //A Closure
    def test(Closure c){
        c.delegate = this;
        c();
     
    }
 
    static void main(args){
        MethodCallsInClosure m = new MethodCallsInClosure();
        //invoking calls inside the Closure and pass to the methods
        m.test{m.call1(); m.call2()}
        m.test1{m.call1(); m.call2()}
    }
    //another way of Closure
    def test1 = {
        it.delegate = this;
        it.doCall();
        it();
    }

}


prints :
Call 1
Call 2
Call 1
Call 2
Call 1
Call 2