A prerequisite for writing a DSL is understanding some advanced programming techniques like yielding blocks, Ruby's method lookup process and method_missing(), etc. Reading Metaprogramming Ruby is the best way to develop these advanced Ruby skills (the book also contains a section on writing internal DSLs).
I wrote a blog post on how to create a Ruby DSL to generate HTML markup in about 20 lines of code. It's much better to start with some small toy examples, than to jump right in to a production-grade application like Erector. Studying the source code of the Docile gem as suggested by ms-tg is excellent, but it still might be a bit overwhelming as your first DSL. Learn some advanced Ruby programming techniques, build some toy examples, and then study the Docile source code.
Here's how to get some of the functionality of the Docile gem as explained by @ms-tg from scratch:
def dsl(obj, &block)
obj.instance_eval(&block)
end
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
obj = Pizza.new
dsl(obj) do |pizza|
pizza.cheese = true
pizza.pepperoni = true
pizza.sauce = :extra
end
p obj
# => #
The dsl() method can also be used for more trivial examples, like the Docile README example of constructing an array:
arr = []
dsl(arr) do
push(1)
push(2)
pop
push(3)
end
p arr