2008-10-02 13 views
6

Tôi đang viết một DSL trong Ruby để điều khiển dự án Arduino mà tôi đang thực hiện; Bardino. Đó là một con khỉ thanh sẽ được kiểm soát phần mềm để phục vụ đồ uống. Arduino lấy lệnh thông qua cổng nối tiếp để báo cho Arduino biết cần bật máy bơm nào và trong bao lâu.Cần trợ giúp cải thiện Ruby DSL để điều khiển bộ phân phối đồ uống có kiểm soát Arduino (bar monkey)

Hiện tại nó đang đọc công thức (xem bên dưới) và in lại. Mã cho truyền thông nối tiếp vẫn cần phải được làm việc cũng như một số ý tưởng khác mà tôi đã đề cập dưới đây.

Đây là DSL đầu tiên của tôi và tôi đang làm việc với một ví dụ trước để nó rất thô ráp xung quanh các cạnh. Bất kỳ phê bình, cải tiến mã (có bất kỳ tài liệu tham khảo tốt cho thực hành tốt nhất Ruby DSL hoặc thành ngữ?) Hoặc bất kỳ ý kiến ​​chung.

Tôi hiện đang có một dự thảo thô của DSL do đó, một công thức uống trông giống như sau (Github link):

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

này lần lượt được giải thích và hiện kết quả như sau (Github link):

[[email protected] barduino-tender]$ ruby barduino-tender.rb examples/water.rb 
Preparing: Simple glass of water 

Ingredients: 
Water: 2 ounces 

Đây là một khởi đầu tốt cho DSL, tuy nhiên, tôi nghĩ rằng nó có thể được triển khai tốt hơn một chút. Một số ý tưởng tôi đã có bên dưới:

  1. Xác định "thành phần" có sẵn bằng cách sử dụng tên thành phần và máy bơm số được kết nối với. Có thể sử dụng băm? ingredients = {"water" => 1, "vodka" => 2}. Bằng cách này, khi một thành phần được hiểu, nó có thể là a) gửi số máy bơm qua cổng nối tiếp, sau đó là số lượng ounce cho Arduino phân phối b) cho người dùng biết rằng thành phần không tồn tại và hủy bỏ vì vậy không có gì được phân phối c) dễ dàng có khả năng thay đổi hoặc thêm thành phần mới nếu chúng thay đổi.
  2. Làm cho công thức trông ít mã hơn, đó là mục đích chính của DSL, có thể xây dựng công cụ xây dựng công thức? Sử dụng các thành phần có sẵn để nhắc người dùng cho một tên đồ uống, các thành phần có liên quan và bao nhiêu?

Dự án Github là here, vui lòng ngã ba và thực hiện yêu cầu kéo hoặc đăng đề xuất và ví dụ về mã của bạn để những người dùng khác xem. Và nếu bạn tò mò, mã Arduino, sử dụng khung phát triển Ruby Arduino là here.

Cập nhật

tôi sửa đổi và làm sạch mọi thứ lên một chút để phản ánh Orion Edwards gợi ý cho một công thức. Nó bây giờ trông giống như sau.

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

Tôi cũng đã thêm một hàm băm (khóa là thành phần và giá trị số máy bơm được kết nối). Tôi nghĩ rằng điều này cung cấp nhiều tiến bộ. Tôi sẽ để lại câu hỏi mở cho bất kỳ đề xuất thêm cho bây giờ, nhưng cuối cùng sẽ chọn câu trả lời của Orion. Mã DSL cập nhật là here.

+0

Để thêm một số mã giả vào danh sách kết hợp. cho thành phần trong thành phần {if ingredients.exists? serial.send (pump_number) chờ 1 giây serial.send (số tiền) chờ OK từ Arduino để tiếp tục thành phần tiếp theo} – mwilliams

Trả lời

5

Nếu không nhìn vào chi tiết thực hiện (hoặc liên kết github của bạn), tôi muốn thử viết một DSL như thế này:

(ăn cắp từ đây: 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 

Hy vọng rằng sẽ giúp!

+0

bạn có thể đặt 0.5.ounces.of: vodka nếu bạn cảm thấy thích nó, tôi chỉ tìm thấy bí danh cho ' một nửa 'để dễ đọc hơn –

+0

Cảm ơn lời khuyên đó, đó thực sự là _a lot_ dễ đọc hơn và tôi sẽ điều chỉnh cho phù hợp trong bản sửa đổi tiếp theo. – mwilliams

1

DSL của Orion trông rất đẹp. Thay đổi duy nhất tôi có thể đề xuất từ ​​mã "cập nhật" của bạn là

  1. Thay thế description bằng recipe. Đây là cụm từ mô tả hơn
  2. Vì tập hợp thành phần và hành động được cố định, hãy liên kết các thành phần với biến thay vì ký hiệu, tức là bạn có vodka = :vodka được xác định một nơi nào đó. Dễ nói hơn là

    trộn vodka, gin và triple_seC# thay vì sử dụng: vodka,: gin và: triple_sec.

anyways đó là một nit nhỏ.

+1

Cá nhân tôi không đồng ý với các thành phần ràng buộc với các biến, bởi vì, các biến được thiết kế để thay đổi. ràng buộc với một biến ngầm "nói" với nhà phát triển đó. 'vodka' không bao giờ được phép bị ràng buộc lại thực sự là 'phô mai'. –

+0

đồng ý với thay thế 'mô tả' bằng 'recipe_for' hoặc tương tự –

3

Nếu bạn muốn các công thức để trông tự nhiên hơn, tại sao không (từ công thức tương tự Orion Ewards sử dụng, cảm ơn!):

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) 

Sau đó thêm Treetop để trộn. Bạn có thể có các quy tắc như:

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 

Trình biên dịch treetop nào sẽ chuyển thành mô-đun ruby ​​đẹp. Sau đó:

parser = CocktailParser.new 
r = parser.parse(recipe) 
Các vấn đề liên quan