Playing with call() using Groovy Metaprogramming

2 min read
Share:

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

comments ( 2 )

Leave a Reply

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