How Tree Syntax works in Groovy

Thanks to Jame's feedback I've been making steady progress in learning Groovy.

Today I had a few minutes and wanted to learn more about how the tree syntax mechanism works. What I found was surprisingly simple and elegant. Instead of this feature being a special part of the language, it's just a cool use of the core Groovy features. Imagine code like this.


builder = NodeBuilder.newInstance();
builder.people() {
person("Pete");
person("Jayne");
}


The code builder.people() is evaluated as a simple method call. In Groovy a method is called by calling the invokeMethod() method on the objects class. So at runtime this code will call BuildSupport.invokeMethod(...'people'...). The BuilderSupport base class (base class of NodeBuilder) has overridden invokeMethod() and rather than attempting to find and execute the method 'people', as most classes would do, the builder class instead creates a new Node with the name of the method - in this case 'people'.



The block

{ 

person("Pete");
person("Jayne");
}
is also just core Groovy syntax, in this case its a Closure that's executed in the context of people (and builder). If you aren't familiar with Closures I'm not the one to explain them to you. But the short description is they are (very cool) anonymous callback methods that inherit the context of the object which they are called from. As this Closure executes it attempts to run the person() methods on the people Node() (via Node.invokeMethod(...'person')), but that fails because Node doesn't have a method called 'people', the Closure then falls back on its 'delegate' object and attempt to execute the person method again. The 'delegate' object in this case is the NodeBuilder so instead of actually looking for a methods called person() , just as before, it makes the new Nodes of that name.
This is very cool OO stuff.


Comments

Popular posts from this blog

Shark Crackers

Running roughshod or ripshod

Axis, Axes, Axii?