2009-10-12 14 views

Trả lời

11

Khi bạn sử dụng API, bạn khởi tạo đối tượng và phương thức gọi theo cách bắt buộc. Mặt khác một DSL tốt nên được khai báo, đại diện cho các quy tắc và các mối quan hệ trong miền vấn đề của bạn, không phải hướng dẫn được thực hiện. Hơn nữa lý tưởng DSL nên được đọc và sửa đổi bởi ai đó không phải là một lập trình viên (mà không phải là trường hợp với các API).

Cũng xin lưu ý sự khác biệt giữa DSL nội bộ và bên ngoài.

  • Tên miền nội bộ cụ thể được nhúng bằng ngôn ngữ lập trình (ví dụ: Ruby). Thật dễ dàng để triển khai thực hiện, nhưng cấu trúc của DSL phụ thuộc vào ngôn ngữ gốc được nhúng vào.
  • Ngôn ngữ riêng bên ngoài là ngôn ngữ riêng được thiết kế với tên miền cụ thể.Nó mang lại cho bạn sự linh hoạt hơn khi nói đến cú pháp, nhưng bạn phải triển khai mã để giải thích nó. Nó cũng an toàn hơn, vì người chỉnh sửa quy tắc miền không có quyền truy cập vào tất cả sức mạnh của ngôn ngữ gốc.
+0

+1 để tạo sự khác biệt giữa DSL nội bộ và bên ngoài. – ctford

+1

Cảm ơn vì tiền thưởng, bây giờ tôi có thể cảm thấy như Boba Fett: P –

4

DSL (ngôn ngữ miền cụ thể) là một thuật ngữ quá mức. Nếu bạn chỉ đơn giản là sử dụng một tập hợp con của một ngôn ngữ (nói Ruby), làm thế nào nó là một ngôn ngữ khác với bản gốc? Câu trả lời là, nó không phải là. Tuy nhiên, nếu bạn thực hiện một số tiền xử lý văn bản nguồn để giới thiệu cú pháp mới hoặc ngữ nghĩa mới không được tìm thấy trong ngôn ngữ chính thì bạn thực sự có một ngôn ngữ mới, có thể là tên miền cụ thể.

+0

Vì vậy, nếu tôi ghi đè toán tử '<<' để làm điều gì đó khác với những gì nó thường làm trên một đối tượng đơn giản trong Ruby, đó là "cú pháp mới"? Hay nó chỉ là cú pháp mới nếu nó chưa bao giờ được thấy trong bất kỳ ngôn ngữ nào trước đây? – Chuck

+0

Tôi không nghĩ rằng cú pháp đó phải hoàn toàn mới lạ để đáp ứng các yêu cầu cho một DSL mới. Tôi phải thừa nhận rằng không có sự nhất trí cho dù đơn vị vận hành quá tải có đủ để tạo DSL đặc biệt khi bạn bị mắc kẹt với các quy tắc ưu tiên hiện tại hay không và các vấn đề khác (ví dụ: ngữ nghĩa đánh giá ngắn mạch của || và && trong C++) . – cdiggins

+0

Hoàn toàn đồng ý về điều này. Vấn đề là bạn tìm thấy nhiều người hoàn toàn chắc chắn rằng họ có một định nghĩa vững chắc về những gì làm cho một DSL, nhưng không ai trong số họ đồng ý! Trong thực tế mọi thứ chỉ là ít nhiều DSL-y, với các ngôn ngữ như Ruby và Lisp khuyến khích phong cách, và các ngôn ngữ như Java làm cho nó chết tiệt gần như không thể. – gtd

2

Sự kết hợp giữa chế độ thơ của Ruby và quá tải toán tử hiện tại có khả năng có thứ gì đó đồng thời là cú pháp Ruby hợp pháp và DSL hợp lý.

Và tình tiết tăng nặng tiếp tục có nghĩa là XML không cho thấy có lẽ là DSL đơn giản được xây dựng vào tất cả các tập tin cấu hình không phải là hoàn toàn sai lầm ..

2

Tạo một DSL:

  • Thêm phương pháp mới để lớp Object để bạn có thể gọi chúng như thể chúng được xây dựng trong các cấu trúc ngôn ngữ. (xem rake)

  • Tạo các phương thức trên đối tượng tùy chỉnh hoặc tập hợp các đối tượng và sau đó có tệp tập lệnh chạy các câu lệnh trong ngữ cảnh của đối tượng cấp cao nhất. (Xem capistrano) thiết kế

API:

  • phương pháp tạo trên một đối tượng tùy chỉnh hoặc thiết lập các đối tượng, vì vậy người dùng tạo ra một đối tượng sử dụng phương pháp này.

  • Tạo phương thức làm phương thức lớp, để người dùng đặt trước tên lớp trước tất cả các phương thức.

  • Tạo các phương thức làm bản mixin mà người dùng bao gồm hoặc mở rộng để sử dụng các phương pháp trong đối tượng tùy chỉnh của họ.

Vì vậy, có, đường thẳng giữa chúng. Nó là tầm thường để biến một tập hợp các đối tượng tùy chỉnh thành một DSL bằng cách thêm một phương thức chạy một tệp kịch bản lệnh trong ngữ cảnh đúng.

1

Sự khác biệt giữa DSL và API với tôi là DSL có thể ít nhất được hiểu (và xác minh) nếu không được viết dưới dạng ngôn ngữ con của Ruby bởi ai đó trong miền đó.

Ví dụ: bạn có thể có nhà phân tích tài chính viết quy tắc cho một ứng dụng giao dịch chứng khoán trong Ruby DSL và họ sẽ không bao giờ phải biết họ đang sử dụng Ruby.

1

Trên thực tế, chúng giống nhau. DSL thường được thực hiện thông qua các cơ chế ngôn ngữ bình thường trong Ruby, vì vậy về mặt kỹ thuật chúng là tất cả các API.

Tuy nhiên, để mọi người nhận ra một thứ gì đó dưới dạng DSL, nó thường kết thúc bằng việc thêm những gì giống như câu lệnh khai báo cho các lớp hiện có. Một cái gì đó giống như các trình xác nhận hợp lệ và các khai báo quan hệ trong ActiveRecord.

class Foo << ActiveRecord::Base 
    validates_uniqueness_of :name 
    validates_numericality_of :number, :integer_only => true 

end 

trông giống như một DSL, trong khi sau không:

class Foo <<ActiveRecord::BAse 
    def validate 
    unless unique? name 
     errors.add(:name, "must be unique") 
    end 

    unless number.to_s.match?(/^[-]?\d$/) 
     errors.add(:number, "must be an integer") 
    end 
    end 
end 

Họ cả hai sẽ được thực hiện bằng cách mã Ruby bình thường. Nó chỉ là một trong những hình như bạn đã có cấu trúc ngôn ngữ mới mát mẻ, trong khi người khác có vẻ khá cho người đi bộ (và quá chi tiết, vv.)

Các vấn đề liên quan