DSLs in Ruby

Wow, Do We All Get a Language?

Dave Burt

Melbourne Ruby Nuby Night
28 June 2007

Ruby's cool, but it's not for everybody.

Sometimes you just want to write in a language that is tailored to the problem you're dealing with.

What is a DSL?

  • Domain-Specific Programming Language
  • Uses terms that are packed with meaning in the context of the domain
  • Therefore, concisely describes problems/solutions in that area

A DSL — Rubix Cube Moves

Describes a set of steps to change a Rubix Cube.

Is it a programming language? Yes, it clearly and unambiguously describes an algorithm.

You could programmatically change a virtual cube, or instruct a robot how to move a real one, or display clear instructions to a user...

A DSL — HR Management

No extraneous language; any HR Manager can read this.

It's also valid Ruby code.

A DSL — Dungeon

You can imagine what this does in the context of describing a dungeon.

It's Ruby, too.

A DSL — Database table definition

SQL is another DSL.

This is valid Ruby code; it's a DSL that does the same thing as SQL DDL.

A DSL — HTML templating

HTML is another DSL.

This is valid Ruby code; it's a DSL that could be compared to PHP -- leveraging programmability from Ruby but still focused on clearly describing a document

A DSL — Invoicing

Still Ruby, still clear and concise, using domain-specific language almost exclusively.

A DSL — Workflow

You can see a fairly complex construct can be described naturally if you are using the right language.

Types of DSL

A DSL — DOT

With a new language, you can have exactly any syntax you imagine to be ideal.

But you have to build your own parser and interpreter. (Though there are tools to help you do this, such as Ruby's Racc and Parser, Unix's yacc and bison, etc.)

This is the DOT language for describing directed graphs. This code produces the graph below when interpreted. (Ruby's RDoc tool uses this to describe class heirarchies graphically.)

A DSL — Rake

If you're building on an existing language, you can utilise features of the host language.

Rake describes interdependent tasks and required files; the steps to perform and build them, respectively, are written in Ruby code.

How to make a DSL

Let's make a potentially useful DSL now.

Write code in the language

We want to describe a slideshow just like this.

We've made sure We're using valid Ruby syntax.

Make it do what you want it to

We could write an interpreter that displays the slideshow interactively, but for simplicity, we'll convert it into a slideshow format that can be displayed in a browser (using Eric Meyer's S5 format).

To do this, we'll make a library we can require in the slideshow definition that will make the code we've already written produce XHTML on STDOUT when executed.

Make it do what you want it to

This part is no more difficult than writing code in the new language.

We just need to define the words the DSL uses; in this case, three methods will do.

I've left a couple of string constants and a new string instance method to be defined.

Make it do what you want it to

Here are the missing definitions, but this part is obvious and unenlightening.

Done

After adding the line "require 'slideshow'" to the top of my_presentation.rb, it becomes a Ruby program.

We run that program and dump its output into an HTML file.

That HTML file can be displayed just like this one.

References