问题
What are the good online tutorials on how to implement DSLs in Ruby? I am looking for hands-on examples that explain the whole process.
I am aware that there is this question on good books about DSLs and Ruby: Good books on Ruby based DSL.
回答1:
I think this is a great series of articles on building a dsl in ruby:
http://jroller.com/rolsen/entry/building_a_dsl_in_ruby
回答2:
You can make this very easy with the Docile gem, either by using the gem, or by reading the source code in order to understand how it works.
Say you want to make a Pizza via a DSL
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
And you use a builder pattern to make the Pizza
class PizzaBuilder
def cheese(v=true); @cheese = v; end
def pepperoni(v=true); @pepperoni = v; end
def bacon(v=true); @bacon = v; end
def sauce(v=nil); @sauce = v; end
def build
Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce)
end
end
And you want a DSL, say something like
@sauce = :extra
pizza do
bacon
cheese
sauce @sauce
end
# => should return Pizza.new(true, false, true, :extra)
All you have to do is define the pizza method as
require 'docile'
def pizza(&block)
Docile.dsl_eval(PizzaBuilder.new, &block).build
end
And bang, you're done.
回答3:
I find this tutorial very good, as it explicitly covers the two very important patterns of using yield
and instance_eval
:
How do I build DSLs with yield and instance_eval?
回答4:
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
# => #<struct Pizza cheese=true, pepperoni=true, bacon=nil, sauce=:extra>
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
来源:https://stackoverflow.com/questions/4936146/tutorials-for-writing-dsl-in-ruby