Hướng dẫn trực tuyến tốt về cách triển khai DSL trong Ruby là gì? Tôi đang tìm những ví dụ thực hành giải thích toàn bộ quá trình.Hướng dẫn viết DSL trong Ruby
Tôi biết rằng có câu hỏi này về sách hay về DSL và Ruby: Good books on Ruby based DSL.
Hướng dẫn trực tuyến tốt về cách triển khai DSL trong Ruby là gì? Tôi đang tìm những ví dụ thực hành giải thích toàn bộ quá trình.Hướng dẫn viết DSL trong Ruby
Tôi biết rằng có câu hỏi này về sách hay về DSL và Ruby: Good books on Ruby based DSL.
Tôi nghĩ rằng đây là một loạt lớn các bài viết về việc xây dựng một dsl trong ruby:
Bạn có thể làm điều này rất dễ dàng với các Docilegem, hoặc bằng đá quý, hoặc bằng cách đọc the source code để hiểu cách hoạt động của nó.
Giả sử bạn muốn thực hiện một Pizza qua một DSL
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
Và bạn sử dụng một mô hình builder để làm cho Pizza
class PizzaBuilder
def cheese(v=true); @cheese = v; end
def pepperoni(v=true); @pepperoni = v; end
def bacon(v=true); @bacon = v; end
def sauce(v=nil); @sauce = v; end
def build
Pizza.new([email protected], [email protected], [email protected], @sauce)
end
end
Và bạn muốn có một DSL, nói điều gì đó như
@sauce = :extra
pizza do
bacon
cheese
sauce @sauce
end
# => should return Pizza.new(true, false, true, :extra)
Tất cả bạn phải làm là xác định bánh pizza phương pháp như
require 'docile'
def pizza(&block)
Docile.dsl_eval(PizzaBuilder.new, &block).build
end
Và bang, bạn đã hoàn tất.
tôi thấy hướng dẫn này rất tốt, vì nó bao gồm một cách rõ ràng hai mô hình rất quan trọng của việc sử dụng yield
và instance_eval
:
Tôi đang tìm kiếm ví dụ này mà tôi đã đọc khi tôi còn là người mới bắt đầu. Đây là một trong những ví dụ tốt nhất mà tôi đã đọc về việc xây dựng một DSL. –
Một điều kiện tiên quyết để viết một DSL là sự hiểu biết một số kỹ thuật lập trình tiên tiến như khối năng suất , Phương thức tra cứu phương thức của Ruby và method_missing(), vv Đọc Metaprogramming Ruby là cách tốt nhất để phát triển các kỹ năng Ruby tiên tiến này (cuốn sách cũng chứa một phần viết các DSL nội bộ).
Tôi đã viết blog post on how to create a Ruby DSL to generate HTML markup trong khoảng 20 dòng mã. Tốt hơn hết là bắt đầu với một số ví dụ đồ chơi nhỏ, hơn là nhảy ngay vào một ứng dụng cấp sản xuất như Erector. Nghiên cứu mã nguồn của Docile gem theo gợi ý của ms-tg là tuyệt vời, nhưng nó vẫn có thể hơi lấn át như DSL đầu tiên của bạn. Tìm hiểu một số kỹ thuật lập trình Ruby nâng cao, xây dựng một số ví dụ về đồ chơi và sau đó nghiên cứu mã nguồn Docile.
Dưới đây là làm thế nào để có được một số chức năng của đá quý ngoan ngoãn như được giải thích bởi @ ms-tg từ đầu:
def dsl(obj, &block)
obj.instance_eval(&block)
end
Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce)
obj = Pizza.new
dsl(obj) do |pizza|
pizza.cheese = true
pizza.pepperoni = true
pizza.sauce = :extra
end
p obj
# => #<struct Pizza cheese=true, pepperoni=true, bacon=nil, sauce=:extra>
Phương pháp dsl()
cũng có thể được sử dụng cho các ví dụ tầm thường hơn, như Docile README ví dụ về xây dựng một mảng:
arr = []
dsl(arr) do
push(1)
push(2)
pop
push(3)
end
p arr
Chắc chắn, bạn có thể sử dụng 'instance_eval' trần truồng, nhưng sau đó bạn sẽ không thể sử dụng biến mẫu hoặc biến cục bộ và bạn sẽ không thể chuỗi ngữ cảnh (nghĩ DSL đa cấp, phổ biến) . Điều đó có ý nghĩa? Vì vậy, những gì Docile bổ sung là các giải pháp tiêu chuẩn cho những vấn đề này, để các dự án không phải tiếp tục khám phá và phát minh lại bánh xe về điều này. –
-1 vì, trong khi Docile chắc chắn rất đẹp, sử dụng nó * bỏ qua * quá trình viết một DSL thông thường thay vì giải thích cách thực hiện. – 00dani
@ 00Davo trong khi bạn được hưởng ý kiến của mình, đó là một cử chỉ rất không thân thiện. Đặc biệt là xem xét mã nguồn cho Docile là một cách tuyệt vời để tìm hiểu cách tạo một DSL trong ruby. –
Hmm. Tôi đã xem qua nguồn, và bạn nói đúng; nó thực sự khá minh họa. Tôi sẽ thay đổi phiếu bầu của mình nhưng cũng khuyên bạn nên chỉnh sửa câu trả lời để bao gồm một tham chiếu đến nguồn Docile. (Oh. Tôi vừa thử và dường như lá phiếu của tôi bị khóa trong khi câu trả lời không được chỉnh sửa, vì vậy bạn sẽ thực sự * cần * để chỉnh sửa, có vẻ như?) – 00dani