Tutorials for writing DSL in Ruby [closed]

空扰寡人 提交于 2019-11-27 05:12:55

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!