Archive for December 9th, 2009

Groovy @Delegate annotation

Posted on December 9, 2009. Filed under: Groovy |

Groovy 1.7 provides some nice new annotations. One of those annotations is the @Delegate. What it essentially does, is providing the methods of the Delegate to the class using the Delegate. This is best explained by a small example:

class Employee {
   def doWork() {  "work!" }
}

class Manager {
   @Delegate Employee employee = new Employee()
}

manager = new Manager()
assert "work!" == manager.doWork()

This works really nice. The Manager now delegates the call for doWork() to the Employee. This is quite powerful, and works really nice and easy.

However, what happens when the Manager has two delegates?

class Cleaner {
   def clean() { "clean" }
   def doWork() { "doWork" }
}

class Employee {
   def doWork() {  "work!" }
}

class Manager {
   @Delegate Cleaner cleaner = new Cleaner()
   @Delegate Employee employee = new Employee()
}

manager = new Manager()

assert "work!" == manager.doWork()
assert "clean" == manager.clean()

This also works really nice. Now the Manager has two delegates, and it can delegate the clean method to the Cleaner, and the doWork method to the Employee. However, since I’m quite curious, and had a small twiscussion with @darthvader42 on this: what happens when the names of the Delegates clash, ie. the Cleaner and Employee both have a method with the same name. This is demonstrated below:

class Cleaner {
   def doWork() { "clean" }
}

class Employee {
   def doWork() {  "work!" }
}

class Manager {
   @Delegate Employee employee = new Employee()
   @Delegate Cleaner cleaner = new Cleaner()
}

manager = new Manager()

assert "work!" == manager.doWork()
assert "clean" == manager.doWork()

This fails! Argh! What happens? The console output is fortunately very clear:


assert "clean" == manager.doWork()
| | |
| | work!
| Manager@2e6a54f9
false

What happened, is that Groovy picked the first Delegate it encountered, and uses those methods. The Cleaner doWork is not called anymore, since all calls to doWork are handled by the Employee.

Conclusion
The @Delegate is a very handy annotation to handle some of the plumbing code for you, but just beware of the results when using more than two @Delegates. Btw, while writing this conclusion, I was also curious what would happen if the Manager itself has a doWork method. As I expected, the doWork method of the Manager takes precedence over that of it’s delegates, so the doWork method of the Manager itself is called!

Read Full Post | Make a Comment ( 4 so far )

Liked it here?
Why not try sites on the blogroll...