Wednesday, July 18, 2007

Method missing in Groovy - Part 2

In my previous post I showed how to use invokeMethod to provide "method missing" behaviour in Groovy. Well, if you're prepared to live on the cutting edge and install the latest Groovy 1.1 beta 3 code from SVN then you can try out Groovy's new "method missing" feature that will be more familiar to Ruby programmers.

This came about after I had a productive discussion with Charles Nutter of JRuby, and in the spirit of cross pollination here is the example from my previous post using the new "method missing" feature of the upcoming Groovy 1.1 release:


1 def dynamicMethods = [...]
2 Book.metaClass.'static'.methodMissing = { String methodName, args ->
3 StaticMethodInvocation method =
4 dynamicMethods.find { it.isMethodMatch(methodName) }
5 if(method) {
6 Book.metaClass.'static'."$methodName" = { Object[] varArgs ->
7 method.invoke(Book.class, methodName, varArgs)
8 }
9 result = method.invoke(Book.class, methodName, args)
10 }
11 else {
12 throw new MissingMethodException(methodName, Book.class, args)
13 }
14 result
15 }


So what is the difference between this and invokeMethod? Well invokeMethod will deal with every method call and hence has a certain amount of overhead. The behaviour of invokeMethod is more useful for AOP type use cases where you need to intercept a method call and wrap behaviour around the invocation.

The "method missing" approach will only take effect when a method is not found to invoke using the normal runtime and hence has no additional overhead plus the code is a bit more concise. Thanks for the help Charles! ;-)

4 comments:

Anonymous said...

That's pretty clever Graeme, I suppose GORM will receive a face-lift with the next release of Groovy.

Graeme Rocher said...

It already has, we're working against the snapshots :-)

Anonymous said...

Great! a related question, will builders have a considerable impact with this? the usual impl relies on invokeMethod, with this change it seems adequate to override methodMissing only.

Graeme Rocher said...

I haven't thought about modifying builders just yet, but yes it makes sense