X

Sundararajan's Weblog

  • Java
    October 18, 2006

Higher order messages in Groovy

Guest Author

I came to know about higher order messages (HOM) - messages that take another message as argument - from here: Higher Order Messaging in Ruby. Then, I read this paper: Higher Order Messaging


To implement higher-order messages with Ruby, two things are used
  • method_missing - a way to handle messages when method to handle it is missing.
  • Open classes - classes may be modified "after" creation [For example, add methods to an existing class]


Implementing higher-order messages with Groovy

In a blog entry, I mentioned about doesNotUnderstand in Groovy. But, there are no open classes in Groovy. But, Groovy supports class categories - a facility by which we can "add" methods to existing classes (within a specific "use" context).


// A class that forwards any message
// to it to the objects of the list
// and returns the result list
class Do {
def list
Do(l) { list = l }
def invokeMethod(String name, args) {
list.collect { it.invokeMethod(name, args) }
}
}
// A class that filters the objects of the list
// using the message invoked on it
class Where {
def list
Where(l) { list = l }
def invokeMethod(String name, args) {
list.findAll { it.invokeMethod(name, args) }
}
}
// A class that sorts the objects of a list
// using the message invoked on it
class Order {
def list
Order(l) { list = l }
def invokeMethod(String name, args) {
list.sort { it.invokeMethod(name, args) }
}
}
// A class category that "adds" methods to List
// class
class ListCategory {
static def getDo(List list) {
return new Do(list);
}
static def getWhere(List list) {
new Where(list);
}
static def getOrderBy(List list) {
new Order(list);
}
}
// we use our List category
use(ListCategory) {
strings = ["JavaScript", "JRuby", "Java", "Groovy", "BeanShell"]
// find all strings that start with "J"
println strings.where.startsWith("J")
// make a list of upper case strings
println strings.do.toUpperCase()
// sort the strings by length
println strings.orderBy.length()
}

As you can see, with higher-order messages, we avoid closures in the method call-chain - making the method chain easily readable.

Join the discussion

Comments ( 1 )
  • Andres Almiray Sunday, October 22, 2006
    This tip is really useful for writing DSLs with Groovy, specially for testing.
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.