领域特定语言(DSL)是一种针对特定领域优化的小型语言。由于 DSL 有明确的针对性,它允许使用者声明自己_想要什么_,而不是_如何去_做,因此能极大地提升工作效率和理解程度。
它的一个常见应用领域是复杂的自定义和配置。
例如,DOT 语言允许你用文本描述一张图,然后由 Graphviz 工具(比如dot)将其转换成图片。一个简单的图长这样:
graph {
graph [bgcolor="yellow"]
a [color="red"]
b [color="blue"]
a -- b [color="green"]
}
把这段内容放进文件example.dot,再运行dot example.dot -T png -o example.png,就会生成一张example.png图片:黄色背景上,一个红色圆圈和一个蓝色圆圈由一条绿色线相连。
请编写一个类似 Graphviz dot 语言的领域特定语言。
我们的 DSL 与 Graphviz dot 语言相似,都是用来创建图数据结构的。不过,与 DOT 语言不同,我们的 DSL 是一种内部 DSL,只在本语言中使用。
在这道练习中,你可以完全自由地设计你梦想中的图 DSL。
也许你想基于标签和记录列表来创建 DSL,像这样:
my_graph =
Graph.create([
Title("My Graph"),
Node("a", { color: Green }),
Node("b", { color: Blue }),
Edge("a", "b", { style: Dotted }),
])
又或者,你更想基于函数调用链来设计 DSL,像这样:
my_graph =
Graph.create()
.with_title("My Graph")
.add_node("a", Attr.create().with_color(Green))
...
也可能你有一个完全不同的方案?那就放手去做吧!测试只要求你创建几个特定的图,至于怎么构建,完全由你决定。
话虽如此,如果 DSL 清晰、简洁,而且不会太出人意料,通常会更好(例如,minus函数是用来做减法的,而不是用来在两个节点之间建立一条边,比如node("a") - node("b"))。
想让乐趣加倍的话,你还可以选择实现一个to_dot函数,把你的图转换成 DOT 格式!