我正在用 Ruby 编写 DSL 来控制我正在从事的 Arduino 项目;巴迪诺。这是一个酒吧猴子,将由软件控制以提供饮料。Arduino 通过串行端口接收命令,告诉 Arduino 要打开哪些泵以及打开多长时间。
它当前读取一个配方(见下文)并将其打印出来。串行通信的代码以及我在下面提到的其他一些想法仍然需要处理。
这是我的第一个 DSL,我正在处理前面的示例,所以它的边缘非常粗糙。任何批评、代码改进(对于 Ruby DSL 最佳实践或习语有什么好的参考吗?)或任何一般性评论。
我目前有一份 DSL 的草稿,所以饮料配方如下所示(Github 链接):
desc "Simple glass of water"
recipe "water" do
ingredients(
"Water" => 2.ounces
)
end
这反过来被解释,目前结果如下(Github 链接):
[mwilliams@Danzig barduino-tender]$ ruby barduino-tender.rb examples/water.rb
Preparing: Simple glass of water
Ingredients:
Water: 2 ounces
这对于 DSL 来说是一个好的开始,但是,我确实认为它可以实现得更好一些。我有以下一些想法:
- 使用成分的名称和它所连接的数字泵来定义可用的“成分”。也许使用哈希?成分 = {“水” => 1,“伏特加” => 2}。这样,当一种成分被解释时,它可以 a)通过串行端口发送泵号,然后是 Arduino 分配的盎司数 b)告诉用户成分不存在并中止,因此没有分配 c)如果它们被改变,很容易有能力改变或添加新的成分。
- 让菜谱看起来不像代码,这是 DSL 的主要目的,也许构建一个菜谱构建器?使用可用的成分提示用户输入饮料名称、涉及的成分和多少?
Github 项目在这里,请随时 fork 并提出拉取请求,或在此处发布您的代码建议和示例以供其他用户查看。如果您完全好奇,这里是使用 Ruby Arduino 开发框架的 Arduino 代码。
更新
我修改和清理了一些东西,以反映 Orion Edwards 对食谱的建议。现在看起来如下所示。
description 'Screwdriver' do
serve_in 'Highball Glass'
ingredients do
2.ounces :vodka
5.ounces :orange_juice
end
end
我还添加了一个哈希(键是成分和它所连接的泵号的值)。我认为这提供了很大的进步。我暂时将这个问题留待任何进一步的建议,但最终会选择 Orion 的答案。更新的 DSL 代码在这里。