Precisa de ajuda melhorar um rubi DSL para controlar um dispensador de bebida controlado Arduino (barra de macaco)
-
03-07-2019 - |
Pergunta
Eu estou escrevendo um DSL em Ruby para controlar um projeto Arduino Eu estou trabalhando em; Bardino. É um macaco bar que será controlado por software para servir bebidas. O Arduino recebe comandos através da porta serial para contar a Arduino que bombeia para ligar e por quanto tempo.
Ele lê atualmente uma receita (veja abaixo) e imprime-lo de volta. O código para comunicação serial ainda precisa ser trabalhado em, bem como algumas outras idéias que mencionei abaixo.
Esta é minha primeira DSL e eu estou trabalhando fora de um exemplo anterior por isso é muito áspero em torno das bordas. Quaisquer críticas, melhorias de código (existem boas referências para Ruby DSL melhores práticas ou expressões idiomáticas?) Ou quaisquer comentários gerais.
Eu tenho atualmente um rascunho do DSL Assim, uma receita da bebida parece com o seguinte ( Github ligação ):
desc "Simple glass of water"
recipe "water" do
ingredients(
"Water" => 2.ounces
)
end
Esta por sua vez é interpretado e atualmente resultados com o seguinte ( Github ligação ):
[mwilliams@Danzig barduino-tender]$ ruby barduino-tender.rb examples/water.rb
Preparing: Simple glass of water
Ingredients:
Water: 2 ounces
Este é um bom começo para o DSL, no entanto, eu acho que poderia ser implementado um pouco melhor. Algumas idéias que tive abaixo:
- Definir o que "ingredientes" estão disponíveis usando o nome do ingrediente e a bomba número que ele está conectado. Talvez usando um hash? ingredientes = { "água" => 1, "vodka" => 2}. Desta forma, quando um ingrediente é interpretado isso pode a) enviar o número da bomba sobre o porto de série, seguido pelo número de onças para o Arduino para dispensar b) informar ao usuário esse ingrediente não existe e abort para que nada seja dispensado c) facilmente ter a capacidade de alterar ou adicionar novos ingredientes se eles estão alterados.
- Fazendo o olhar receita menos código como, que é o principal objetivo de um DSL, talvez construir um construtor de receita? Usando os ingredientes disponíveis para solicitar ao usuário um nome de bebida, ingredientes envolvidos e quanto?
O projeto Github é aqui , sinta-se livre para garfo e fazer puxar pedidos, ou postar suas sugestões de código e exemplos aqui para que outros usuários vejam. E se você está em tudo, o código Arduino Curioso, usando o framework Ruby Arduino Desenvolvimento é aqui .
Atualizar
I modificado e limpas as coisas um pouco para refletir Orion Edwards sugestão para uma receita. Agora parece que o seguinte.
description 'Screwdriver' do
serve_in 'Highball Glass'
ingredients do
2.ounces :vodka
5.ounces :orange_juice
end
end
Eu também acrescentou um hash (chave é o ingrediente eo valor do número da bomba que está ligado a). Eu acho que esta muito progresso fornecido. Vou deixar a questão em aberto para quaisquer sugestões para agora, mas acabará por selecionar a resposta de Orion. O código de DSL atualizado é aqui .
Solução
Sem olhar para os detalhes de implementação (ou seus links github), eu tentaria escrever uma DSL como esta:
(roubando aqui: http://supercocktails.com/1310/Long -Island-Iced-chá )
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
Espero que ajude!
Outras dicas
Se você quiser a receita para uma aparência mais natural, por que não (a partir da mesma receita Orion Ewards utilizado, graças!):
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)
Em seguida, adicione Treetop à mistura. Você poderia ter regras, tais como:
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
Qual o compilador copa vai se transformar em um módulo ruby ??agradável. Então:
parser = CocktailParser.new
r = parser.parse(recipe)
DSL de Orion parece muito bom. A única mudança que eu possivelmente sugerir de você "atualizados" código é
- Substitua
description
comrecipe
. É um termo mais descritivo -
Uma vez que o conjunto de ingredientes e ações é fixo, ligam os ingredientes para variáveis ??em vez de símbolos ou seja você tem
vodka = :vodka
definido em algum lugar. Sua é mais fácil dizermisturar vodka, gin e triple_sec # em vez de usar: vodka,: gin e:. Triple_sec
de qualquer maneira isso é um menor nit.