DSL Support in Brail, Part I
The BeginningFirst, none of this is even possible without mentioning what the Boo project team has done and giving a bit of a background - to my understanding - of what's at the core. With the 0.7.8 release of Boo, the team enabled the ability to invoke methods of an object via Boo's macro syntax. What's that mean; and what's a macro? C# developers have been using -- no, well, ok, pun intended -- since C# was introduced. In C#, using() is or can be thought of as a macro as when the C# compiler finds a using() block, it expands it into a try/catch/finally block calling dispose on the instance referenced in the using statement. Here's an example; this code:
using(SqlConnection c = new SqlConnection())
// do stuff
is rewritten/transformed by the compiler to:
SqlConnection c = null;
c= new SqlConnection()
if(c != null)
which is why the using statement only accepts types that implement IDisposable, as it ensures Dispose() is always called. So, basically, macros are shorthand for developers.
Back to Boo. The 0.7.8 release allows developers to invoke methods using the macro syntax. So if I had a method called text that took a string as a parameter:
def text(value as string):
in Boo 0.7.8, I can call text like this:
text "hello world"
Well, that's all well and good, isn't it? Nothing really "magical" there; how does this enable DSLs in Brail?
The AwakeningOne of the major advantages that Boo offers developers is the ability to extend the language in numerous ways and macros is just one, "simple" option developers have at their disposal. The only caviaet is that your macros, obviously, need to produce valid, compilable code. So, from the example above, when the compiler parses:
text "hello world"
it rewrites/transforms the source to:
So, how, or rather what, does a MonoRail view in Brail that's something like this:
text "Untitled page"
text "Hello World"
Give you the output you expect?
The ImplementationAs you might guess, "dsl" is a macro that takes one parameter: the language you intend to use. So what does "dsl Html" generate? This, in Boo:
dsl = Castle.MonoRail.Views.Brail.DslProvider(self)
or, in C#:
DslProvider dsl = new Castle.MonoRail.Views.Brail.DslProvider(this);
Okay, that might be a lot to swallow. "dsl Html" starts off by creating a new instance of a DslProvider object. The DslProvider object acts as a registry of languages to use. In this case, the second line tells the DslProvider that we're specifically interested in working with the HtmlExtension.
What's up with "this" and "OutputStream"? Here's where we get into the real nitty gritty, and for that, I leave you to Part II in this series. Hope this is as interesting for you as it is for me!!