Нужна помощь в улучшении Ruby DSL для управления диспенсером напитков, управляемым Arduino (bar monkey)

StackOverflow https://stackoverflow.com/questions/164095

Вопрос

Я пишу DSL на Ruby для управления проектом 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. Определение того, какие "ингредиенты" доступны, используя название ингредиента и номер насоса, к которому он подключен.Может быть, используя хэш?ингредиенты = {"вода" => 1, "водка" => 2}.Таким образом, когда ингредиент интерпретируется, он может либо: а) отправить номер насоса через последовательный порт, за которым следует количество унций, которые Arduino должен выдать; б) сообщить пользователю, что ингредиент не существует, и прервать выдачу, чтобы ничего не выдавалось; в) легко иметь возможность изменять или добавлять новые ингредиенты, если они были изменены.
  2. Чтобы рецепт выглядел менее похожим на код, что является основной целью DSL, может быть, создать конструктор рецептов?Использование доступных ингредиентов для запроса у пользователя названия напитка, используемых ингредиентов и их количества?

Проект Github - это здесь, не стесняйтесь разветвлять и делать запросы на извлечение или размещайте свои предложения по коду и примеры здесь, чтобы их могли увидеть другие пользователи.И если вам вообще интересно, код Arduino, использующий платформу разработки Ruby Arduino, является здесь.

Обновить

Я немного изменила и подчистила все, чтобы отразить предложение Ориона Эдвардса по рецепту.Теперь это выглядит следующим образом.

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-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

Надеюсь, это поможет!

Другие советы

Если вы хотите, чтобы рецепт выглядел более натурально, почему бы и нет (по тому же рецепту, который использовал Орион Эвардс, спасибо!):

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)

Затем добавьте Верхушка дерева к смеси.У вас могли бы быть такие правила, как:

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)

DSL от Orion выглядит очень красиво.Единственное изменение, которое я бы, возможно, предложил вам от "обновленного" кода, - это

  1. Заменить description с recipe.Это более описательный термин
  2. Поскольку набор ингредиентов и действий фиксирован, привяжите ингредиенты к переменным, а не к символам, т.е. у вас есть vodka = :vodka определенный где-то.Это легче сказать

    смешайте водку, джин и triple_sec # вместо использования :vodka, :gin и :triple_sec.

в любом случае, это мелкая гнида.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top