Tuesday, May 21, 2013

Call all the things!

At Gradle's core is a really nice set of Collection classes, which I wish were exposed on their own. The central feature is the idea around the all(Closure action) method, which says "run this Closure on every object", including ones added later. This is defined in DomainObjectCollection and it's leveraged by a few other methods. Specifically withType(Class<S> type, Closure configureClosure)and it's generalization matching(Closure spec). While they're very similar to Groovy's (and other languages) findAll or each, the extra temporal dimension makes it much more power for an API designer. Typically an API would provide a Collection which delegates to another collection while putting some triggers in place when something is added. With DomainObjectCollection, the user could create the collection and even prep it before passing it into an API call. It also allows multiple people to essentially register listeners, sorta like a property listener. In the following example, I configure other parts of the model based on what they all, for any value added or which will be added.

Loading ....
Another useful generic Collection is NamedDomainObjectCollection<T> (with its supporting implementations). These allow a collection to be built up with the assumption that each has a unique name, and it's really not too far from a Map with the key being the name. The magic comes from being able to build up an instance with methodMissing calls. The resulting calls look really slick and screams "DSL", I wish I had it for every Groovy DSL I write. As you can see in the next sample is a minimal way to create a list, which also has the ability to be configured for each item.
Loading ....