Necesita ayuda para mejorar un DSL Ruby para controlar un dispensador de bebidas controlado por Arduino (bar monkey)

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

Pregunta

Estoy escribiendo un DSL en Ruby para controlar un proyecto Arduino en el que estoy trabajando; Bardino Es un mono de barra que será controlado por software para servir bebidas. El Arduino toma comandos a través del puerto serie para decirle al Arduino qué bombas encender y por cuánto tiempo.

Actualmente lee una receta (ver más abajo) y la imprime nuevamente. El código para las comunicaciones en serie todavía necesita ser trabajado, así como algunas otras ideas que he mencionado a continuación.

Este es mi primer DSL y estoy trabajando en un ejemplo anterior, por lo que es muy difícil. Cualquier crítica, mejoras de código (¿hay alguna buena referencia para las mejores prácticas o modismos de Ruby DSL?) O algún comentario general.

Actualmente tengo un borrador del DSL, por lo que una receta de bebida tiene el siguiente aspecto ( enlace de Github ):

desc "Simple glass of water"
recipe "water" do
  ingredients(
  "Water" => 2.ounces
  )
end

Esto a su vez se interpreta y actualmente resulta con lo siguiente ( Enlace de Github ):

[mwilliams@Danzig barduino-tender]$ ruby barduino-tender.rb examples/water.rb
Preparing: Simple glass of water

Ingredients:
 Water: 2 ounces

Este es un buen comienzo para el DSL, sin embargo, creo que podría implementarse un poco mejor. Algunas ideas que tuve a continuación:

  1. Definir qué "ingredientes" están disponibles usando el nombre del ingrediente y el número de bomba al que está conectado. Tal vez usando un hash? ingredientes = {" agua " = > 1, `` vodka '' = > 2}. De esta manera, cuando se interpreta un ingrediente, puede a) enviar el número de la bomba por el puerto serie seguido de la cantidad de onzas para que el Arduino dispense b) decirle al usuario que el ingrediente no existe y abortar para que no se dispense c) tener la capacidad de cambiar o agregar nuevos ingredientes fácilmente si se cambian.
  2. Hacer que la receta se vea menos codificada, ¿cuál es el propósito principal de una DSL? ¿Usando los ingredientes disponibles para solicitar al usuario el nombre de una bebida, los ingredientes involucrados y cuánto?

El proyecto Github es aquí , siéntase libre de bifurcar y hacer tirar solicitudes, o publique sus sugerencias de código y ejemplos aquí para que otros usuarios lo vean. Y si tiene curiosidad, el código Arduino, que usa el marco de desarrollo Ruby Arduino es aquí .

Update

Modifiqué y limpié un poco las cosas para reflejar la sugerencia de Orion Edwards de una receta. Ahora se parece a lo siguiente.

description 'Screwdriver' do 
  serve_in 'Highball Glass'
  ingredients do
    2.ounces :vodka
    5.ounces :orange_juice
  end
end

También agregué un hash (la clave es el ingrediente y el valor del número de bomba al que está conectado). Creo que esto proporcionó mucho progreso. Dejaré la pregunta abierta para cualquier sugerencia por ahora, pero finalmente seleccionaré la respuesta de Orion. El código DSL actualizado es aquí .

¿Fue útil?

Solución

Sin mirar los detalles de implementación (o sus enlaces de github), intentaría escribir un DSL como este:

(robando desde aquí: 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

¡Espero que eso ayude!

Otros consejos

Si quieres que la receta se vea más natural, ¿por qué no? (de la misma receta que usó Orion Ewards, ¡gracias!):

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)

Luego agregue Treetop a la mezcla. Podría tener reglas 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

Que el compilador de treetop se transformará en un bonito módulo ruby. Entonces:

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

El DSL de Orion se ve muy bien. El único cambio que posiblemente sugeriría de usted "actualizado" el código es

  1. Reemplace descripción con receta . Es un término más descriptivo
  2. Dado que el conjunto de ingredientes y acciones es fijo, une los ingredientes a variables en lugar de símbolos, es decir, tienes vodka =: vodka definido en algún lugar. Es más fácil decirlo

    mezcle vodka, gin y triple_sec # en lugar de usar: vodka,: gin y: triple_sec.

de todos modos, eso es un problema menor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top