Wednesday, February 10, 2010

Groovy Category and Dynamic Overriding

A Category class is an ordinary class which contains set of methods. The class can be used for a duration of code block and when used first parameter type of each method treats the declared method as its member method.

class TestCategory{
static def test(String str){
return "testing"
}
}

use(TestCategory){
// test() can be called as a member method inside the use block
assert "testing" == "a".test()
}

A category class can contain method without any parameters but it is not possible to use such method in the use block. A category class method should at least have one parameter to get called from the use block. The following code will throw an exception at the time of execution.

class EmptyMethodCategory{
static def emptyMethod(){
return "empty"
}
}

use(EmptyMethodCategory){
assert "empty" == emptyMethod()
}

Operator overriding is the most suitable use of the Category classes. In case of operator overriding, if the caller is not matching with any of the overridden methods, original method will be executed.

class StringSumCategory{
static def plus(String str1, String str2){
return str1.toInteger() + str2.toInteger()
}
}

use(StringSumCategory){
assert 3 == "1" + "2"
assert "12" == "1" + 2
}

If the category class contains a method with only one parameter of type Object, that method will be available to any possible type in Groovy.

class SerializeCategory{
static def serialize(Object obj){
// do serialization stuff
return serializedObj
}
}

use(SerializeCategory){
println 1.serialize()
println "a".serialize()
println ([1, 2, 3].serialize())
println this.serialize()
println serialize()
}

Groovy is full of surprises. It contains some of the best features from many static and dynamic languages.

No comments:

Post a Comment