forked from jashkenas/coffeescript
-
Notifications
You must be signed in to change notification settings - Fork 58
[Extensibility] Writing DSLs
StanAngeloff edited this page Sep 15, 2010
·
14 revisions
The CoffeeScript grammar is pretty flexible when it comes to writing a DSL. Implicit parentheses, commas and objects combine to give you an expressive language which compiles to good old JavaScript. The examples on this page assume a good level of knowledge of CoffeeScript.
Let's look at an example of what we are trying to accomplish before we get started:
# DSL
describe 'Whiskey'
age: 18
brand: 'Jack'
# Usage
glass = new Whiskey()
puts glass.age # 18
To implement our custom describe
function let's first look at the generated JavaScript for it:
describe('Whiskey')({
age: 18,
brand: 'Jack'
});
We have a call to the function itself and a following one to its returned value. CoffeeScript makes it easy to implement such chaining:
# Implementation
describe = (name) -> (properties) ->
window[name] = class
constructor: ->
(@[name] = value) for name, value of properties
Example:
# DSL and usage
a = keyA: 'valueA'
b = keyB: 'valueB'
extend b, using a
puts b.keyA # 'valueA'
This compiles to fairly simple JavaScript:
extend(a, using(b));
To implement this we only need a few lines of CoffeeScript:
# Implementation
using = (obj) -> obj
extend = (obj, using) -> (obj[key] = value) for key, value of using