Skip to content

Instantly share code, notes, and snippets.

@christoph-daehne
Last active September 4, 2020 03:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christoph-daehne/a7b60503799c64f6afbf to your computer and use it in GitHub Desktop.
Save christoph-daehne/a7b60503799c64f6afbf to your computer and use it in GitHub Desktop.
// our configuration model
class BouquetConfiguration extends ArrayList<String> {
int howMany(String flower) {
return this.count { it == flower }
}
String toString() {
return "Bouquet: " + this.toString()
}
}
// our DSL keyword
class BouquetConfigurationDsl {
private final BouquetConfiguration bouquet
BouquetConfigurationDsl(BouquetConfiguration bouquet) {
this.bouquet = bouquet
}
void flower(String flower) {
bouquet << flower
}
}
class Bouquet {
static BouquetConfiguration create(
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BouquetConfigurationDsl) Closure script
) {
def bouquet = new BouquetConfiguration()
script.resolveStrategy = Closure.DELEGATE_ONLY
script.delegate = new BouquetConfigurationDsl(bouquet)
script()
return bouquet
}
}
def bouquet = Bouquet.create {
flower "cornflower"
flower "cornflower"
flower "poppy"
flower "calendula"
}
println bouquet
// our configuration model
class BouquetConfiguration {
private final List<String> flowers = []
// method for use at runtime
int howMany(String flower) {
return flowers.count { it == flower }
}
// DSL keyword for use at DSL execution
void flower(String flower) {
flowers << flower
}
String toString() {
return "Bouquet: " + flowers.toString()
}
}
class Bouquet {
static BouquetConfiguration create(
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BouquetConfiguration) Closure script
) {
def bouquet = new BouquetConfiguration()
script.resolveStrategy = Closure.DELEGATE_ONLY
script.delegate = bouquet
script()
return bouquet
}
}
def bouquet = Bouquet.create {
flower "cornflower"
flower "cornflower"
flower "poppy"
flower "calendula"
}
println bouquet
class BouquetConfiguration extends ArrayList<String> {
int howMany(String flower) {
return this.count { it == flower }
}
String toString() {
return "Bouquet: " + this.toString()
}
}
class FloristConfiguration {
final Map<String, BouquetConfiguration> catalog = [:]
String toString() {
return "Florist: " + catalog.toString()
}
}
class BouquetConfigurationDsl {
private final BouquetConfiguration bouquet
BouquetConfigurationDsl(BouquetConfiguration bouquet) {
this.bouquet = bouquet
}
void flower(String flower) {
bouquet << flower
}
}
class FloristConfigurationDsl {
private final FloristConfiguration florist
FloristConfigurationDsl(FloristConfiguration florist) {
this.florist = florist
}
BouquetConfiguration bouquet(
String name,
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = BouquetConfigurationDsl) Closure script
) {
def bouquet = florist.catalog[name]
if (bouquet == null) {
bouquet = florist.catalog[name] = new BouquetConfiguration()
}
script.resolveStrategy = Closure.DELEGATE_ONLY
script.delegate = new BouquetConfigurationDsl(bouquet)
script()
return bouquet
}
}
class Florist {
static FloristConfiguration create(
@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = FloristConfigurationDsl) Closure script
) {
def florist = new FloristConfiguration()
script.resolveStrategy = Closure.DELEGATE_ONLY
script.delegate = new FloristConfigurationDsl(florist)
script()
return florist
}
}
def florist = Florist.create {
bouquet "meadow", {
flower "cornflower"
flower "cornflower"
flower "poppy"
flower "calendula"
}
bouquet "roses", {
flower "rose"
flower "rose"
flower "rose"
flower "rose"
}
// add another calendula to existing bouquet
bouquet "meadow", {
flower "calendula"
}
}
println florist
class HelloWorldService {
// this function becomes a keyword in our DSL
void printHelloWorld() {
println("Hello World")
}
}
class HelloWorldScript {
static void execute(Closure script) {
// here we wire the colure with the service
script.delegate = new HelloWorldService()
// i explain this line in a later example ;)
script.resolveStrategy = Closure.DELEGATE_ONLY
// the closure is executed in the context of its delegate
script()
}
}
HelloWorldScript.execute {
printHelloWorld()
for(def i = 0; i < 10; i++) {
printHelloWorld()
}
}
class HelloWorldService {
void printHelloWorld() {
println("Hello World")
}
}
class HelloWorldScript {
// by annotating the parameter we gain syntax highlighting and auto-completion
static void execute(@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = HelloWorldService) Closure script) {
script.resolveStrategy = Closure.DELEGATE_ONLY
script.delegate = new HelloWorldService()
script()
}
}
HelloWorldScript.execute {
printHelloWorld()
for(def i = 0; i < 10; i++) {
printHelloWorld()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment