2012-02-21 33 views
7

Tôi làm cách nào để sử dụng -spec từ trong erlang? Vui lòng cho tôi ý tưởng sử dụng hiệu quả từ này. Có phải là viết tắt cho mục đích tài liệu?Thông số kỹ thuật cho các chức năng: -spec. Sử dụng hiệu quả

Tôi cố gắng áp dụng một ràng buộc để hoạt động trong mô-đun theo đặc tả loại chức năng sử dụng -spec, nhưng tôi đã thất bại - không có hạn chế nào được áp dụng.

Trả lời

18

-spec thuộc tính thực sự được xử lý bởi trình biên dịch và hệ thống thời gian chạy làm tài liệu. Bạn không thể thêm bất kỳ "tính năng thực thi" nào vào mã của mình bằng cách sử dụng chúng và áp dụng cho các thuộc tính -type-opaque.

Tuy nhiên họ có ích như:

  • Documentation: họ sử dụng bởi EDoc để tạo ra tất cả các hình thức khác nhau của tài liệu cho mã của bạn. Các thuộc tính -spec là các chữ ký chức năng, tùy thuộc vào mức độ nỗ lực bạn đưa vào chúng, có thể làm cho mã của bạn dễ hiểu hơn và dễ bảo trì hơn. Giả sử rằng cấu trúc dữ liệu yêu thích của bạn trong tháng này là dict(). Hãy xem xét mã sau:

    my_function(SomeArg, SomeOtherArg, Dict) -> 
        ... 
        dict:find(SomeKey, Dict) 
        ... 
    

    Biến đang được sử dụng làm dict được đặt tên như vậy. Nhưng chúng ta hãy nói rằng bạn có đoạn như sau:

    my_other_function(NamesDict, PlacesDict) -> 
        ... 
        R1 = my_function(A, B, NamesDict), 
        ... 
        R2 = my_function(C, D, PlacesDict), 
    ... 
    

    Đang cố gắng để theo kịp với tình trạng này sẽ dẫn đến mã mà lặp đi lặp lại Dict hậu tố này. Thậm chí nhiều hơn, bạn thậm chí có thể không muốn nhớ trong ngữ cảnh của my_other_function rằng hai đối số là dict(). Vì vậy, thay vào đó bạn có thể muốn làm điều này:

    -spec my_other_function(dict(), dict()) -> atom(). 
    
    my_other_function(Names, Places) -> 
        ... 
        R1 = my_function(A, B, Names), 
        ... 
        R2 = my_function(C, D, Places), 
        ... 
    

    Bây giờ rõ ràng là những lập luận này nên dict() cho các chức năng để làm việc và hy vọng mọi người sẽ có thể để con số đó mà không đi sâu vào các mã.Nhưng giả sử bạn đang sử dụng Namedict() ở những nơi khác và nó lưu trữ một số thông tin cụ thể được hiển thị với các API khác nhau. Sau đó, nó là một ứng cử viên hoàn hảo cho một tuyên bố -type:

    -type names() :: dict(). 
    
    -spec my_other_function(names(), places()) -> atom(). 
    
    my_other_function(Names, Places) -> 
        ... 
        R1 = my_function(A, B, Names), 
        ... 
        R2 = my_function(C, D, Places), 
        ... 
    

    Nếu ai đó làm thường xuyên sử dụng cấu trúc dữ liệu đặc biệt này, bạn có thể muốn xuất nó quá:

    -module(my_module). 
    
    -export_type([names/0]). 
    
    -type names() :: dict(). 
    

    module khác bây giờ có thể tham khảo này cấu trúc dữ liệu cụ thể:

    -module(my_other_module). 
    
    -record(my_state, {names :: my_module:names(), 
            ...}). 
    

    Cuối cùng nếu bạn muốn nhà phát triển khác không kiểm tra cấu trúc dữ liệu này theo bất kỳ cách nào trong mô-đun, bạn có thể clare nó như -opaque. Một lần nữa, đây là một "gợi ý thân thiện", cũng như tất cả những thứ còn lại cho đến nay. Hoặc là nó...?

  • phát hiện Khác biệt: Nếu bạn dành thời gian để sử dụng -specs-types bạn sẽ rất giống mà chúng được lưu giữ đến nay. Đó là kiến ​​thức phổ biến mà không ai duy trì tài liệu cập nhật nếu không có ai xem! May mắn thay, Dialyzer đang xem. Dialyzer có thểcheck rằng trong tất cả các cuộc gọi đến my_function() các đối số là dict() (nó có thể làm điều này ngay cả khi không có chú thích -spec nhưng nó dễ dàng hơn nếu có) và hét lên giết người đẫm máu nếu bạn gọi nó với cái gì khác. Nó có thể tiếp tục theo dõi các loại được xuất khẩu này và thậm chí báo cáo các vi phạm về độ mờ đục. Vì vậy, nó không phải là "chỉ tài liệu".

  • testcase hệ: thích có thể sử dụng các định nghĩa -spec-type tự động kiểm tra các chức năng của bạn với testcases ngẫu nhiên. Nó có khả năng để làm cho testcases ngẫu nhiên thậm chí từ tờ khai như thế này:

    -type int_tree() :: {node, integer(), tree(), tree()} | nil. 
    
  • Các thương hiệu phương pháp mới để xác định một tập hợp các callbacks cho một hành vi là sử dụng -spec cú pháp quen thuộc. Trình biên dịch, Dialyzer và các công cụ khác có thể sử dụng thông tin này để kiểm tra việc thực hiện hành vi. Xem thêm trong OTP hành vi nào codehere

Read more here.

+0

Cảm ơn bạn đã trả lời chi tiết.'-opaque' có giống với' -type' không có khai báo '-export_type' không? – egor7

+0

Không, bạn vẫn cần xuất bất kỳ loại '-opaque' nào mà bạn khai báo. – aronisstav

8

-spec 's cho các chức năng là thông số kỹ thuật mà có một số nơi họ giúp:

  • Họ đóng vai trò như tài liệu hướng dẫn của hàm. Tạo EDoc sẽ kéo các thông số kỹ thuật và làm cho chúng có sẵn trong tài liệu.
  • Chúng là đặc điểm kỹ thuật cho máy quay số. Khi dialyzer chạy nó sẽ sử dụng các thông số kỹ thuật để xác định xem mã có sai theo bất kỳ cách nào hay không. Đó là, nếu bạn spec là sai - và trong một số trường hợp nó sẽ giúp hệ thống để hiểu chính xác lý do tại sao mã là sai quá.
  • Chúng là một công cụ có giá trị trong đặc tả của hành vi. Có một từ khóa -callback mới có thể được sử dụng để làm điều này cho các API hành vi.
  • Chúng có giá trị để xây dựng một bộ xương kiểu về cách chương trình phù hợp với nhau và từ nơi dữ liệu đến.
  • Cùng với người anh em họ -type-opaque bạn có thể buộc một số loại nhất định mờ đục thành từng phần mã. Điều đó có nghĩa là bạn không được phép xem biểu diễn bên trong trên một mức xác minh tĩnh. Điều này có thể giúp bạn lái mã mô-đun hóa vì bạn không được phép kết hợp chặt chẽ các đoạn mã.
+0

Cảm ơn bạn, nhưng hãy giúp tôi với câu lệnh cuối cùng. Sự khác nhau giữa '-type' và' -opaque' là gì. Chúng ta chỉ có thể sử dụng '-type' vào một mô-đun duy nhất, và nếu chúng ta muốn nó hiển thị, chúng ta phải cung cấp từ' -export_type'. Đây có phải là cùng một cụm từ '-type' và' -opaque' nếu chúng ta không sử dụng từ '-export_type' không? – egor7

+0

Bạn có thể vui lòng trỏ đến một số tài liệu về từ khóa '-callback' mới này không? Ví dụ: –

+0

Ivan, xem http://www.erlang.org/doc/design_principles/spec_proc.html#id72728. Tôi có rất nhiều niềm vui nhìn qua tất cả các tài liệu erlang để tìm một điều này hay cách khác. Có vẻ như Erlang guys viết tất cả các tài liệu có giá trị ở phần cuối của gần như tất cả các tài liệu - Mans, nguyên tắc hệ thống, referencese. Vì vậy, nếu bạn muốn bắt đầu viết và hiểu các chương trình erlang, bạn nên đọc tài liệu từ dưới lên trên) – egor7

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