Нужна помощь в улучшении Ruby DSL для управления дозатором напитков, контролируемым Arduino (барная обезьяна) - PullRequest
6 голосов
/ 02 октября 2008

Я пишу DSL на Ruby для управления проектом Arduino, над которым я работаю; Bardino. Это барная обезьяна, которая будет контролироваться программным обеспечением для подачи напитков. Arduino принимает команды через последовательный порт, чтобы сообщить Arduino, какие насосы включить и как долго.

В настоящее время он читает рецепт (см. Ниже) и печатает его обратно. Код для последовательной связи все еще нуждается в разработке, а также некоторые другие идеи, которые я упомянул ниже.

Это мой первый DSL, и я работаю над предыдущим примером, поэтому он очень грубый по краям. Любые критические замечания, улучшения кода (есть ли хорошие ссылки на лучшие практики Rubi DSL или идиомы?) Или какие-либо общие комментарии.

В настоящее время у меня есть черновик DSL, поэтому рецепт напитка выглядит следующим образом ( Github link ):

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, "vodka" => 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-код здесь .

Ответы [ 3 ]

5 голосов
/ 03 октября 2008

Не глядя на детали реализации (или ваши ссылки на 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

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

3 голосов
/ 14 декабря 2008

Если вы хотите, чтобы рецепт выглядел более натурально, почему бы и нет (из того же рецепта, который использовал 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)
1 голос
/ 03 октября 2008

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

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

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

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

...