5
(require '[clojure.spec :as s])

次のデータを検討してください。

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

これは、ベクトルのベクトルの値を持つ :names という 1 つのキーを持つハッシュマップです。内部ベクトルには、最初の要素として文字列を含める必要があり、オプションでキーワード :lucky を 2 番目の要素として含めることができます。

前の 2 つの文は次のように説明する必要がありますclojure.spec。ベクター内の項目から始めましょう。

(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

これは機能します。ただし、オプションが1つしかない場合。解析された結果は次のように良くなりませんか?

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

これは clojure.spec で実行できますか?

これにより、次のことができます。

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

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

ただし、テストに合格したように見えますが、アイテムが解析されなくなったのはなぜですか?

編集: これは、alpha7 から alpha10 リリースに切り替えることで解決できます。coll-of は引数を 1 つしか取りません。

最後に、私の仕様は次のようになり、前述の警告があります。

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

1 に答える 1