(require '[clojure.spec :as s])
rozważyć następujące dane:Analizowanie z clojure.spec
(def data {:names [["Anna" :lucky]
["Peter"]
["Jon" :lucky]
["Andre" :lucky]]})
Jest to hash-mapa z jednego klucza: Nazwy o wartości wektora wektorów. Wektory wewnętrzne muszą zawierać ciąg jako pierwszy element i mogą opcjonalnie zawierać słowo kluczowe: lucky jako drugi element.
Poprzednie dwa zdania powinny być opisane z clojure.spec
- Zacznijmy elementów w wektorze:
(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
To działa. Jeśli jednak jest tylko jedna opcja. Czy analizowany wynik nie będzie wyglądał lepiej:
`{:name "Tom", :lucky true}` or `{:name "Tom", :lucky false}`
Czy można to zrobić w clojure.spec?
Dzięki temu można prowadzić:
(s/def ::items (s/coll-of ::item '()))
(s/conform ::items [["Tom" :lucky] ["Tim"]])
[["Tom" :lucky] ["Tim"]]
Jednak wygląda na to, że przechodzi test ale dlaczego elementy nie są przetwarzane więcej?
Edit:ten może być rozwiązany poprzez przełączenie z alfa7 do uwolnienia alpha10, gdzie pot-of zajmuje tylko jeden argument
Wreszcie moja specyfikacja wygląda, mając wcześniej opisanych Ostrzeżenia:
(s/def ::my-spec (s/keys req-un [::items]))
Tylko boczna uwaga - '# (=: lucky%)' jest lepiej określona jako '# {: lucky}'. –