需要帮助改进Ruby DSL以控制Arduino控制的饮料分配器(条形猴子)

时间:2020-03-06 15:02:41  来源:igfitidea点击:

我正在用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项目在这里,我们可以随意进行分叉和发出拉取请求,或者在此处发布代码建议和示例,以供其他用户查看。如果我们完全好奇,可以在这里使用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代码在这里。

解决方案

在不研究实现细节(或者github链接)的情况下,我将尝试编写这样的DSL:

(从这里偷:http://supercocktails.com/1310/Long-Island-Iced-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的DSL看起来非常不错。
我可能建议我们"更新"的代码唯一的变化是

  • description替换为recipe。这是一个更具描述性的术语
  • 因为成分和动作的集合是固定的,所以将成分绑定到变量而不是符号,即我们在某个地方定义了" vodka =:vodka"。混合使用伏特加,杜松子酒和Triple_sec#比使用:vodka,:gin和:triple_sec更容易。

无论如何,这是个小问题。

如果我们想让配方看起来更自然,为什么不这样做(与使用的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

树梢编译器将其转换为漂亮的ruby模块。然后:

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