Playing with call() using Groovy Metaprogramming
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
Nice,, Loved it…. 🙂
Very cool. Thanks for sharing.