我正在用Ruby编写一个DSL来控制我正在研究的Arduino项目; Bardino。这是一只酒吧猴子,可以通过软件控制饮料。 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. 定义什么“成分”可以使用配料的名称和它所连接的数字泵。也许使用哈希?成分= {" water" => 1,“伏特加” => 2}。这样,当一种成分被解释时,它可以a)通过串口发送泵号,然后是Arduino分配的盎司数b)告诉用户该成分不存在并中止所以没有分配c)如果它们发生变化,很容易就能改变或添加新成分。
  2. 使配方看起来更像代码,这是DSL的主要目的,也许建立一个配方建设者?使用可用的成分提示用户提供饮料名称,成分和含量多少?
  3. Github项目是这里,随意分叉并拉动请求,或在此处发布您的代码建议和示例供其他用户查看。如果你有点好奇,使用Ruby Arduino开发框架的Arduino代码是这里

    <强>更新

    我修改并清理了一些东西以反映Orion Edwards对食谱的建议。它现在看起来如下。

    description 'Screwdriver' do 
      serve_in 'Highball Glass'
      ingredients do
        2.ounces :vodka
        5.ounces :orange_juice
      end
    end
    

    我还添加了一个哈希(键是成分和它连接的泵号的值)。我认为这提供了很多进展。我现在将问题留给任何进一步的建议,但最终将选择猎户座的答案。更新的DSL代码为此处

有帮助吗?

解决方案

无需查看实现细节(或您的github链接),我会尝试编写这样的DSL:

(从这里偷窃: http://supercocktails.com/1310/Long -Island-冰-TEA-

describe "Long Island Iced Tea" do
  serve_in 'Highball Glass'

  ingredients do
    half.ounce.of :vodka
    half.ounce.of :tequila
    half.ounce.of :light_rum
    half.ounce.of :gin
    1.dash.of :coca_cola
    #ignoring lemon peel as how can a robot peel a lemon?
  end

  steps do
    add :vodka, :tequila, :light_rum, :gin
    stir :gently
    add :coca_cola
  end
end

希望有所帮助!

其他提示

如果您希望配方看起来更自然,为什么不呢(来自Orion Ewards使用的相同食谱,谢谢!):

Recipe for Long Island Iced Tea #1
Ingredients:
  1/2 oz Vodka
  1/2 oz Tequila
  1/2 oz Light Rum
  1/2 oz Gin
  1 Dash Coca-Cola
  # ignored Twist of Lemon Peel (or Lime)

然后添加 Treetop 。你可以有以下规则:

grammar Cocktail
  rule cocktail
    title ingredients
  end

  rule title
    'Recipe for' S text:(.*) EOF
  end

  rule ingredients
    ingredient+
  end

  rule ingredient
    qty S liquid
  end
# ...
end

哪个treetop编译器将转换为一个漂亮的ruby模块。然后:

parser = CocktailParser.new
r = parser.parse(recipe)

Orion的DSL看起来非常好看。 我可能建议您进行的唯一更改是“更新”。代码是

  1. description 替换为 recipe 。这是一个更具描述性的术语
  2. 由于成分和动作的组合是固定的,因此将成分绑定到变量而不是符号,即您在某处定义 vodka =:vodka 。它更容易说

    混合伏特加,杜松子酒和triple_sec#而不是使用:伏特加,:杜松子酒和:triple_sec。

  3. 无论如何这是次要的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top