有关如何在Ruby中实现DSL的优秀在线教程是什么?我正在寻找解释整个过程的动手实例。
我知道关于DSL和Ruby的好书有这个问题:Good books on Ruby based DSL。
答案 0 :(得分:35)
我认为这是一篇关于在ruby中构建dsl的一系列文章:
答案 1 :(得分:34)
您可以使用Docile gem轻松完成此操作,方法是使用gem,或者阅读the source code以了解其工作原理。
假设您想通过DSL制作披萨
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
您使用构建器模式来制作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
你想要 DSL ,比如
@sauce = :extra
pizza do
bacon
cheese
sauce @sauce
end
# => should return Pizza.new(true, false, true, :extra)
您所要做的就是将披萨方法定义为
require 'docile'
def pizza(&block)
Docile.dsl_eval(PizzaBuilder.new, &block).build
end
然后砰的一声,你已经完成了。
答案 2 :(得分:4)
我发现本教程非常好,因为它明确涵盖了使用yield
和instance_eval
这两个非常重要的模式:
答案 3 :(得分:1)
编写DSL的先决条件是理解一些高级编程技术,如产生块,Ruby的方法查找过程和method_missing()等。阅读Metaprogramming Ruby是开发这些高级Ruby技能的最佳方法(该书还包含有关编写内部DSL的部分)。
我在大约20行代码中写了blog post on how to create a Ruby DSL to generate HTML markup。从一些小玩具示例开始,要比直接进入像Erector这样的生产级应用程序要好得多。按照ms-tg的建议研究Docile gem的源代码是非常好的,但它仍然可能有点像你的第一个DSL那样压倒一切。学习一些高级Ruby编程技术,构建一些玩具示例,然后研究Docile源代码。
以下是@ms-tg从头开始解释如何获取Docile gem的一些功能:
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>
dsl()
方法也可用于更简单的示例,例如构建数组的Docile README示例:
arr = []
dsl(arr) do
push(1)
push(2)
pop
push(3)
end
p arr