Groovy - DSLS



Groovy allows one to omit parentheses around the arguments of a method call for top-level statements. This is known as the "command chain" feature. This extension works by allowing one to chain such parentheses-free method calls, requiring neither parentheses around arguments, nor dots between the chained calls.

If a call is executed as a b c d, this will actually be equivalent to a(b).c(d).

DSL or Domain specific language is meant to simplify the code written in Groovy in such a way that it becomes easily understandable for the common user. The following example shows what exactly is meant by having a domain specific language.

def lst = [1,2,3,4] 
print lst

The above code shows a list of numbers being printed to the console using the println statement. In a domain specific language the commands would be as −

Given the numbers 1,2,3,4
 
Display all the numbers

So the above example shows the transformation of the programming language to meet the needs of a domain specific language.

Let’s look at a simple example of how we can implement DSLs in Groovy −

class EmailDsl {  
   String toText 
   String fromText 
   String body 
	
   /** 
   * This method accepts a closure which is essentially the DSL. Delegate the 
   * closure methods to 
   * the DSL class so the calls can be processed 
   */ 
   
   def static make(closure) { 
      EmailDsl emailDsl = new EmailDsl() 
      // any method called in closure will be delegated to the EmailDsl class 
      closure.delegate = emailDsl
      closure() 
   }
   
   /** 
   * Store the parameter as a variable and use it later to output a memo 
   */ 
	
   def to(String toText) { 
      this.toText = toText 
   }
   
   def from(String fromText) { 
      this.fromText = fromText 
   }
   
   def body(String bodyText) { 
      this.body = bodyText 
   } 
}

EmailDsl.make { 
   to "Nirav Assar" 
   from "Barack Obama" 
   body "How are things? We are doing well. Take care" 
}

When we run the above program, we will get the following result −

How are things? We are doing well. Take care

The following needs to be noted about the above code implementation −

  • A static method is used that accepts a closure. This is mostly a hassle free way to implement a DSL.

  • In the email example, the class EmailDsl has a make method. It creates an instance and delegates all calls in the closure to the instance. This is the mechanism where the "to", and "from" sections end up executing methods inside the EmailDsl class.

  • Once the to() method is called, we store the text in the instance for formatting later on.

  • We can now call the EmailDSL method with an easy language that is easy to understand for end users.

Advertisements