Creating DSLs in Java, Part 4: Where metaprogramming matters

Experience the power of dynamic methods with Scala and Groovy

1 2 3 4 5 Page 5
Page 5 of 5

Complete code example

Let's put our DSL together and run the program. Listing 8 shows the GameDSL class.

Let's put our DSL together and run the program. Listing 8 shows the GameDSL class.

Listing 8. GameDSL.groovy

class GameDSL
{
  def playersAndScores = [:]

  def players(String[] names)
  {
    names.each { playersAndScores[it] = 0 }
  }

  def getResult()
  {
    def max = -1
    def winner = ''
    playersAndScores.each { name, score ->
      if (score > max)
      {
        max = score
        winner = name
      }
    }

    println "Winner is $winner with a score of $max"
  }

  def methodMissing(String name, args)
  {
    if (playersAndScores.containsKey(name) && args.length == 1 &&  
args[0] instanceof Integer)
    {
      playersAndScores[name] = args[0]
    }
    else
    {
      throw new MissingMethodException(name, this.class, args)
    }
  }

  def propertyMissing(String name) { name }

  def static process(dsl)
  {
    def closure = (Closure) new GroovyShell().evaluate("{->" + dsl +  
"}")
    closure.delegate = new GameDSL()
    closure()
  }
}

Here is the game.dsl file:

players James, John, Jake
James 12
John 14
Jake 9
result

If you'd like to process this DSL from within Groovy code, you could do so like this:

GameDSL.process(new File('game.dsl').text)

If you'd like to process the DSL from within your Java code, type this instead (yes, it's much longer!):

import java.util.Scanner;
import java.io.File;

public class UseDSL
{
  public static void main(String[] args) throws Exception
  {
    String dsl = new Scanner(new File("game.dsl")).useDelimiter("\ 
\Z").next();
    GameDSL.process(dsl);
  }
}

To use the Java example, compile GameDSL.groovy using groovc and UseDSL.java using javac. if you'd prefer, you could use groovyc's joint compilation facility.

So long, farewell ...

This article concludes the Creating DSLs in Java series, where I've introduced you to the fundamentals of domain-specific languages and the various ways to create them on the Java platform. You've learned about the characteristics of internal and external DSLs and where to use each type in your everyday Java-based development. You've also learned why the Java language isn't such a good choice for writing internal DSLs (although it works well for external ones) and seen how you can leverage the strengths of newer Java-platform languages such as Groovy, Scala, and JRuby for this purpose.

See the Resources section to learn more about creating DSLs using the languages discussed in this series.

Dr. Venkat Subramaniam has trained and mentored thousands of software developers in the U.S., Canada, Europe, and Asia. He helps his clients succeed with agile development. He's author of the book .NET Gotchas (O'Reilly), and co-author of the 2007 Jolt productivity award-winning book Practices of an Agile Developer (Pragmatic Bookshelf). Venkat is a frequently invited speaker at international conferences. His latest book is Programming Groovy: Dynamic Productivity for the Java Developer (Pragmatic Bookshelf).

Learn more about this topic

More

1 2 3 4 5 Page 5
Page 5 of 5