Playing with call() using Groovy Metaprogramming

15 / Sep / 2011 by Bhagwat Kumar 2 comments

In groovy you can use "()" with any groovy object which in turn evaluates to invocation of call() method on that object.
For example, the following are valid Groovy statements :
[groovy]
List myList=["one", "two"]
myList()
10()
500 6+5
[name:"Bhagwat", profession:"Software engineer"] name
[/groovy]
Obviously they will throw Runtime exception (MissingMethod/MissingProperty) instead of compilation error. Using meta programming support you can make them happen even though they are Java objects.

Think of this sample groovy code :
[groovy]
List myList=["Apple", "Banana", "Orange"]
myList()
[/groovy]
After executing the above code you will get an exception : “No signature of method: java.util.ArrayList.call() is applicable for argument types: () values: []”.

Here myList() statement is equivalent to myList.call(). This gives us a clue that we can catch method calls like above. Lets inject the call method using groovy metaprogramming in List interface :

[groovy]
List.metaClass.call={index->
delegate.getAt(index) //delegate[index]
}

/* Now the following statements work : */
List myList=["Apple", "Banana", "Orange"]

myList[1] // Using the overloaded operator [] bygroovy

myList.call(1) // index will be 1 ; will return "Banana"
myList(1) // recall the syntax used in Microsoft VB.net to access Array
myList 1 // you can omit parenthesis if there is at least one argument
[/groovy]

We can move one step ahead by passing a Map to the closure to make the method having named parameters :
[groovy]
List.metaClass.call={Map namedArgs->
namedArgs.each{
delegate[it.key]=it.value
}
}

List demo=[]
demo(0:"Java", 1: "Groovy", 2: "Scala")

demo(0) // "Java"
demo(1) // "Groovy"
[/groovy]

When I was learning computer science, I used to write statements like :

[groovy]
x=5
println 5+2(5+x(4)/2) // should be 35
[/groovy]
But that always threw an exception, can you make this work as expected? Give it a try if you really think this blog taught you something. Compare your solution here http://groovyconsole.appspot.com/script/557002.

Hope this let you think in groovy way.
Bhagwat Kumar
bhagwat@intelligrape.com

FOUND THIS USEFUL? SHARE IT

comments (2)

Leave a Reply

Your email address will not be published. Required fields are marked *