2015年5月12日 星期二

[ GroovyGN ] Create Our Own Script Class

Source From Here 
Preface 
Groovy is a great language to write DSL implementations. The Groovy syntax allows for example to leave out parenthesis or semi colons, which results in better readable DSL (which is actually Groovy code). 

One Simple Example 
To run a DSL script we can use the GroovyShell class and evaluate the script. By default the script is evaluated with an instance of groovy.lang.Script class. But we can extends this Script class and write our DSL allowed methods, which can then be used by the DSL script. We pass our own Script class to the GroovyShellwith an CompilerConfiguration object. The CompilerConfiguration allows us to set a new base script class to be used. 
groovy.lang.Script class 
This object represents a Groovy script and contains DSL supported functions

GroovyShell class 
Represents a groovy shell capable of running arbitrary groovy scripts and contains customized groovy.lang.Script class and binding to evaluate input DSL script string.

CompilerConfiguration class 
Compilation control flags and coordination stuff. Wrap customized groovy.lang.Script class and being passed to GroovyShell as argument.


The following sample is a simple DSL to change the state of a Car object. Notice we implicitly access the Car object that is passed to the GroovyShell via abinding. The custom CarScript class can access the car object via the binding and change it's state: 
  1. import org.codehaus.groovy.control.CompilerConfiguration  
  2.   
  3. // Simple Car class to save state and distance.  
  4. class Car {  
  5.     String state  
  6.     Long distance = 0  
  7. }  
  8.   
  9. // Custom Script with methods that change the Car's state.  
  10. // The Car object is passed via the binding.  
  11. abstract class CarScript extends Script {  
  12.     def start() {  
  13.         this.binding.car.state = 'started'  
  14.     }  
  15.   
  16.     def stop() {  
  17.         this.binding.car.state = 'stopped'  
  18.     }  
  19.   
  20.     def drive(distance) {  
  21.         this.binding.car.distance += distance  
  22.     }  
  23. }  
  24.   
  25.   
  26. // Use custom CarScript.  
  27. def compilerConfiguration = new CompilerConfiguration()  
  28. compilerConfiguration.scriptBaseClass = CarScript.class.name  
  29.   
  30. // Define Car object here, so we can use it in assertions later on.  
  31. def car = new Car()  
  32. // Add to script binding (CarScript references this.binding.car).  
  33. def binding = new Binding(car: car)  
  34.   
  35. // Configure the GroovyShell.  
  36. def shell = new GroovyShell(this.class.classLoader, binding, compilerConfiguration)  
  37.   
  38. // Simple DSL to start, drive and stop the car.  
  39. // The methods are defined in the CarScript class.  
  40. def carDsl = '''  
  41. start()  
  42. drive 20  
  43. stop()  
  44. '''  
  45.   
  46. // Run DSL script.  
  47. shell.evaluate carDsl  
  48.   
  49. // Checks to see that Car object has changed.  
  50. assert car.distance == 20  
  51. assert car.state == 'stopped'  
Supplement 
Groovy Doc - ExpandoMetaClass - Domain-Specific Language (2)

沒有留言:

張貼留言

[ Java 文章收集 ] 局部敏感哈希 (Locality-Sensitive Hashing, LSH) 方法介紹

Source From  Here   Preface   本文主要介紹一種用於海量高維數據的近似最近鄰快速查找技術—— 局部敏感哈希  ( Locality-Sensitive Hashing, LSH ),內容包括了 LSH 的原理、LSH 哈希函數集、以及 LSH 的一...