2016-08-29 23 views
5
(require '[clojure.spec :as s]) 

xem xét các dữ liệu sau:Phân tích với clojure.spec

(def data {:names [["Anna"  :lucky] 
        ["Peter"] 
        ["Jon"  :lucky] 
        ["Andre"  :lucky]]}) 

Đó là một hash-bản đồ của với một khóa: tên có giá trị của một vector của vector. Các vectơ bên trong phải chứa một chuỗi như là phần tử đầu tiên và có thể tùy ý chứa một từ khóa: may mắn như là phần tử thứ hai.

Hai câu trước đó nên được mô tả với clojure.spec - Hãy bắt đầu với các mục trong vector:

(s/def ::item (s/cat :name string? :lucky (s/? #(= :lucky %)))) 

(s/conform ::item ["Tom"]) 
;; {:name "Tom"} 
(s/conform ::item ["Tom" :lucky]) 
;; {:name "Tom", :lucky :lucky} 
(s/conform ::item ["Tom" :sad]) 
;; :clojure.spec/invalid 

này hoạt động. Tuy nhiên, nếu chỉ có một tùy chọn. Kết quả không được phân tích cú pháp trông đẹp hơn như thế này:

`{:name "Tom", :lucky true}` or `{:name "Tom", :lucky false}` 

Điều này có thể được thực hiện trong clojure.spec không?

Với điều này, người ta có thể tiếp tục:

(s/def ::items (s/coll-of ::item '())) 

(s/conform ::items [["Tom" :lucky] ["Tim"]]) 
[["Tom" :lucky] ["Tim"]] 

Tuy nhiên, có vẻ như nó vượt qua các bài kiểm tra nhưng tại sao các mục này không được phân tích cú pháp nữa?

Edit: hãy cẩn thậnĐiều này có thể được giải quyết bằng cách chuyển từ alpha7 để phát hành alpha10, nơi coll-of chỉ mất một đối số

Cuối cùng spec của tôi trông như thế nào, có mô tả trước đây:

(s/def ::my-spec (s/keys req-un [::items])) 
+0

Chỉ một lưu ý phụ - '# (=: lucky%)' được mô tả tốt hơn là '# {: lucky}'. –

Trả lời

2

thông số kỹ thuật không được thiết kế để cung cấp chuyển đổi dữ liệu tùy ý (thư viện lõi của Clojure có thể được sử dụng cho điều đó).

Có thể đạt được điều này bằng cách sử dụng s/conformer nhưng không nên sử dụng tính năng đó cho các phép biến đổi tùy ý như thế này (nó phù hợp hơn với những thứ như xây dựng thông số tùy chỉnh).

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