Higher order messages in Groovy

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.

Comments:

This tip is really useful for writing DSLs with Groovy, specially for testing.

Posted by Andres Almiray on October 23, 2006 at 12:23 AM IST #

Post a Comment:
Comments are closed for this entry.
About

sundararajan

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks
Links

No bookmarks in folder

Blogroll

No bookmarks in folder

News

No bookmarks in folder