Fork me on GitHub

Introducing DSLify

21 December 2008

One of the earliest piece of functionality I started working on when I started working on PoolParty was the DSL syntax. Because I wanted the syntax to be light enough where simple inheritance would allow you to introduce new class types and parented models, I wanted to be able to give any method on any object and be able to retrieve it later. The syntax, which looks something like:

cloud :name do
 instances 2..5
end

is so terse and readable, I’ve extracted the functionality into a gem!

Now, you can add your own DSL syntax to any class by adding 1 line to your class! And, you get default syntaxes for free!

Let’s add one for a fake class that we can use to look up showtimes!

First, the class used to look like this:

class MovieFone
end

To add the DSL syntax, we add the 1 line:

class MovieFone
 include Dslify
end

Now, any method that is called on the class MovieFone that doesn’t exist, will be called on the instance. These methods and their attributes are all stored in a method called: __options (double underscores to avoid any collisions with user defined option methods). Now you can fetch any method called on your instance (with or without using =) on the options, or simply by calling the method.

Example? Of course!

class MovieFone
 include Dslify
end

mf = MovieFone.new
mf.movie "Can't buy me love"
mf.times 8.pm..10.pm

# Or, my preferred syntax:

class MovieFone
 def initialize(&block)
  instance_eval block if block
 end
end

MovieFone.new do
 movie "Lucas"
 times 8.pm .. 10.pm
end

One neat feature that may not be apparent is that you can support different runtime methods with the same call, but only have to evaluate it at the runtime. For instance, say you want to give either a range of times (like above) or accept an array of times you are available:

mf.times = 8.pm, 10.pm, 12.am

Simple! When you setup the search method, the argument will be of the class type you send it! Cake!

Find the gem here: http://github.com/auser/dslify/tree/master!