Playing with Boo's DSLs
Boo has gotten a lot better in terms of flexibility lately, a lot better. I was able to churn this little DSL in about an hour:
OnCreate Account: Entity.AccountNumber = date.Now.Ticks OnCreate Order: if Entity.Total > Entity.Account.MaxOrderTotal:
BeginManualApprovalFor Entity
From the perspective of the DSL, it is very easy to use, and from the implementer perspective, this was ridiculously easy to implement.
The only half-way complex thing here is the introduce base class action, which is usually the first approach that you take, which is why I don't consider it complex. Then you can just do create the base class:
abstract class DslBase: [property(Entity)]
entity as objectdef OnCreate(entity as System.Type, action as callable()): Actions.RegisterOnCreate(entity.Name, action) abstract def Execute(): pass def BeginManualApprovalFor(order as Order): print "Starting approval process for Order #${order.Id}"
In the base class you just do what you would normally do, in this case, it just register the new action. Here is the implementation:
class Actions: static onCreateActions = {} static def RegisterOnCreate(entityName as string, action as callable()): onCreateActions[entityName] = action static def OnCreate(entity as object): entityName = entity.GetType().Name action = onCreateActions[entityName] as callable() if not action: print "No action defined for ${entityName}" return dsl = (action.Target as DslBase) dsl.Entity = entity action()
The client code is simply:
SampleDSL().Prepare("Sample.boo") account = Account(MaxOrderTotal: 100) print "Before: ${account.AccountNumber}" Actions.OnCreate( account ) print "After: ${account.AccountNumber}" order = Order(Account: account, Total: 500 ) Actions.OnCreate( order )
All you have left then is to get a rich enough library of methods on the DslBase, for the business user to work with, document how this is done, and that is it.
Comments
Comment preview