Arduino Controlled Drink Dispenser (Bar Monkey)를 제어하기 위해 Ruby DSL을 개선하는 데 도움이 필요합니다.

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

문제

저는 Ruby에 DSL을 작성하여 내가 작업중 인 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}. 이런 식으로, 성분이 해석되면 a) 직렬 포트 위의 펌프 번호를 보내고 Arduino가 분배 할 오른쪽 수를 보내 b) 요소가 존재하지 않고 중단되므로 아무것도 분배되지 않는다고 말합니다. c) 변경되면 새로운 성분을 쉽게 변경하거나 추가 할 수 있습니다.
  2. 레시피를 덜 코드처럼 보이게 만드는 것은 DSL의 주요 목적 인 조리법 빌더를 구축 할 수 있습니까? 사용 가능한 재료를 사용하여 사용자에게 음료 이름, 관련된 재료 및 얼마를 촉구합니까?

Github 프로젝트는입니다 여기, 다른 사용자가 볼 수 있도록 여기에 코드 제안 및 예제를 게시하거나 여기에 주문을 게시하거나 여기에 게시하십시오. 그리고 당신이 전혀 궁금하다면, Ruby Arduino 개발 프레임 워크를 사용하는 Arduino 코드는 다음과 같습니다. 여기.

업데이트

나는 레시피에 대한 Orion Edwards 제안을 반영하기 위해 물건을 약간 수정하고 청소했습니다. 이제 다음과 같습니다.

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

또한 해시를 추가했습니다 (키는 성분과 펌프 번호의 값)을 추가했습니다. 나는 이것이 많은 진전을 제공했다고 생각합니다. 지금은 더 이상의 제안을 위해 질문을 열어 줄 것입니다. 그러나 궁극적으로 Orion의 답변을 선택할 것입니다. 업데이트 된 DSL 코드는입니다 여기.

도움이 되었습니까?

해결책

구현 세부 사항 (또는 GitHub 링크)을 조사하지 않고 다음과 같은 DSL을 작성해 보겠습니다.

(여기서 훔치기 : http://supercocktails.com/1310/long-island-ed-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

도움이되기를 바랍니다!

다른 팁

레시피가 더 자연스럽게 보이기를 원한다면 왜 (동일한 레시피 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)

그런 다음 추가하십시오 나무 꼭대기 믹스에. 다음과 같은 규칙을 가질 수 있습니다.

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 컴파일러가 멋진 루비 모듈로 변환됩니다. 그 다음에:

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

오리온의 DSL은 매우 멋져 보입니다. "업데이트 된"코드가 당신에게 제안 할 수있는 유일한 변경 사항은

  1. 바꾸다 description ~와 함께 recipe. 더 설명적인 용어입니다
  2. 성분과 동작 세트가 고정되어 있으므로 재료를 기호가 아닌 변수에 바인딩합니다. vodka = :vodka 어딘가에 정의되었습니다. 말하기가 더 쉽습니다

    보드카, 진 및 트리플 _sec #을 사용하는 대신 : vodka, : gin and : triple_sec.

어쨌든 그것은 작은 니트입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top