Coffee DSL in Groovy

March 8, 2007 - 3 minute read -
groovy dsl

I thought I'd follow up with my previous post with the Coffee Domain Specific Language in the Groovy Language.

This is really one of my first forays into Groovy, so it's pretty rough. It's really just a direct translation of the Ruby code and not what I would expect to be 'idiomatic Groovy'. I'll try and update this once I learn some more Groovy.

// CoffeeDSL.groovy
// This is the input from the user, likely read from a file
// or input through a user interface of some sort
CoffeeInput = "venti nonfat decaf whip latte"
class Coffee
{
  def size
  def whip
  def caf
  def type
  def milk
  public invokeMethod(name)
  {
    if (['venti', 'grande'].contains(name))
      size = name
    else if (['whip', 'nowhip'].contains(name))
      whip = 'whip'.equals(name)
    else if (['caf', 'decaf', 'halfcaf'].contains(name))
      caf = name
    else if (['regular', 'latte', 'cappachino'].contains(name))
      type = name
    else if (['milk', 'nonfat'].contains(name))
      milk = name
    else
    throw new Exception("Unknown coffee informantion: ${name}.")
  }
  public order() {
    def params = ''
    if (milk)
      params += milk + ' '
    if (caf)
      params += caf + ' '
    if (whip)
      params +=  'whip '
    println("Ordering coffee: ${size} ${params}${type}\n")
  }
  public load(input) {
    // turn one line into multi-line "method calls"
    def cleaned = input.split(/\s+/)
    instance_eval(cleaned)
  }
  public instance_eval(methods) {
    for (method in methods) {
      this.invokeMethod(method)
    }
  }
}
// this is your code which loads the DSL input and executes it
coffee = new Coffee()
coffee.load(CoffeeInput)    // load the user input
coffee.order()                 // submit the order
This isn't even metaprogramming. You could do this in any language, Java, C#, whatever. Everyone talks about metaprogramming in Groovy, but I have not yet found a lot of information on it. Does anyone have any pointers?