Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1

Implementing a Rules DSL


[ 290 ]

Based on these requirements, and with an understanding of how we can structure a
DSL using closures and binding variables, we can make an attempt at how our DSL
might look.


onConsume = { // or on_purchase or on_upgrade
reward ( "Reward Description" ) {
condition {
// Condition(s) that need to apply
}
grant {
// benefits that can accrue
}
}
}

We can implement the conditional nature of the preceding code snippet by using a
binding variable to collect the result of the condition block. The following closure
shows this in action. The condition closure collects the result of its own closure,
which in turn dictates whether the grant closure is invoked.


binding.condition = { closure ->
closure.delegate = delegate

binding.result = (closure() && binding.result)
}

binding.grant = { closure ->
closure.delegate = delegate

if (binding.result)
closure()
}

If the target audience for this DSL were to be only software developers, then this
would be adequate. A single condition block returning a result could fully capture
the logic required to allow or disallow a reward. The problem with this is that
the only way to express multiple conditions is through Groovy conditional logic.
Programmers don't mind reading this, but other audiences for the DSL will quickly
get confused by the Groovy syntax involved. Groovy && and || operators, along
with the operator precedence rules, are not going to make for easy reading for the
general audience.


http://www.ebook3000.com
Free download pdf