Hai bisogno di aiuto per migliorare un Ruby DSL per controllare un distributore di bevande controllato Arduino (barra scimmia)
-
03-07-2019 - |
Domanda
Sto scrivendo un DSL in Ruby per controllare un progetto Arduino a cui sto lavorando; Bardino. È una scimmia da bar che sarà controllata da software per servire bevande. Arduino prende i comandi tramite la porta seriale per dire ad Arduino quali pompe accendere e per quanto tempo.
Attualmente legge una ricetta (vedi sotto) e la stampa di nuovo. Il codice per le comunicazioni seriali deve ancora essere elaborato e alcune altre idee che ho citato di seguito.
Questo è il mio primo DSL e sto lavorando su un esempio precedente, quindi è molto approssimativo attorno ai bordi. Eventuali critiche, miglioramenti del codice (ci sono buone referenze per le best practice o gli idiomi di Ruby DSL?) O eventuali commenti generali.
Al momento ho una bozza approssimativa del DSL, quindi una ricetta per bevande è simile alla seguente ( collegamento Github ):
desc "Simple glass of water"
recipe "water" do
ingredients(
"Water" => 2.ounces
)
end
Questo a sua volta viene interpretato e attualmente risulta con il seguente ( Link Github ):
[mwilliams@Danzig barduino-tender]$ ruby barduino-tender.rb examples/water.rb
Preparing: Simple glass of water
Ingredients:
Water: 2 ounces
Questo è un buon inizio per la DSL, tuttavia, penso che potrebbe essere implementato un po 'meglio. Alcune idee che ho avuto di seguito:
- Definizione di quali "ingredienti" sono disponibili usando il nome dell'ingrediente e la pompa numerica a cui è collegato. Forse usando un hash? ingredienti = {"acqua" = & Gt; 1, "vodka" = & Gt; 2}. In questo modo, quando viene interpretato un ingrediente, può sia a) inviare il numero della pompa sulla porta seriale seguito dal numero di once che Arduino deve erogare b) dire all'utente che l'ingrediente non esiste e interrompere quindi nulla viene erogato c) hanno facilmente la possibilità di cambiare o aggiungere nuovi ingredienti se vengono cambiati.
- Rendere la ricetta meno simile al codice, che è lo scopo principale di una DSL, forse costruire un generatore di ricette? Utilizzando gli ingredienti disponibili per richiedere all'utente un nome di bevanda, ingredienti coinvolti e quanto?
Il progetto Github è qui , sentiti libero di fare fork e fare pull richieste o pubblica qui i suggerimenti e gli esempi di codice che possono essere visualizzati da altri utenti. E se sei curioso, il codice Arduino, usando il framework di sviluppo di Ruby Arduino è qui .
Aggiorna
Ho modificato e ripulito un po 'le cose per riflettere il suggerimento di Orion Edwards per una ricetta. Ora sembra il seguente.
description 'Screwdriver' do
serve_in 'Highball Glass'
ingredients do
2.ounces :vodka
5.ounces :orange_juice
end
end
Ho anche aggiunto un hash (la chiave è l'ingrediente e il valore al numero di pompa a cui è collegato). Penso che ciò abbia fornito molti progressi. Lascerò la domanda aperta per ulteriori suggerimenti per ora, ma alla fine selezionerò la risposta di Orione. Il codice DSL aggiornato è qui .
Soluzione
Senza esaminare i dettagli di implementazione (o i tuoi link github), proverei a scrivere un DSL in questo modo:
(rubando da qui: 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
Spero che ti aiuti!
Altri suggerimenti
Se vuoi che la ricetta appaia più naturale, perché no (dalla stessa ricetta usata da Orion Ewards, grazie!):
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)
Quindi aggiungi Treetop al mix. Potresti avere regole come:
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
Che il compilatore delle cime degli alberi trasformerà in un bel modulo ruby. Poi:
parser = CocktailParser.new
r = parser.parse(recipe)
Il DSL di Orion sembra molto carino. L'unica modifica che potrei suggerire da te " aggiornato " il codice è
- Sostituisci
descrizione
conricetta
. È un termine più descrittivo -
Poiché l'insieme di ingredienti e azioni è fisso, associa gli ingredienti a variabili piuttosto che a simboli, ovvero hai
vodka =: vodka
definito da qualche parte. È più facile da diremescola vodka, gin e triple_sec # invece di usare: vodka,: gin e: triple_sec.
comunque è un valore minore.