2016-07-22 53 views
3

如果我定義了以下記錄:Clojure的規範和記錄構造

(defrecord Person [name id]) 

及以下:

(s/def ::name string?) 
(s/def ::id int?) 
(s/def ::person (s/keys :req-un [::name ::id])) 

我怎麼能保證你不能創建不符合一個人到::人的規格?換句話說,下面應該拋出一個異常:

(->Person "Fred" "3") 

我想:

(s/fdef ->Person :ret ::person) 

但調用:

(->Person "Fred" "3") 

不會引發異常。

但是:

(s/conform ::person (->Person "Fred" "3")) 

不會產生預期:

:clojure.spec/invalid 

感謝

回答

5

fdef:滯留和:FN功能時clojure.spec.test/check測試僅檢查,但你可以使用一個FDEF :args spec在檢測時檢查構造函數的輸入。

(s/fdef ->Person 
    :args (s/cat :name ::name :id ::id) 
    :ret ::person) 

(require '[clojure.spec.test :as stest]) 
(stest/instrument `->Person) 

(->Person "Fred" "3") 

=> CompilerException clojure.lang.ExceptionInfo: Call to #'spec.examples.guide/->Person did not conform to spec: 
In: [1] val: "3" fails spec: :spec.examples.guide/id at: [:args :id] predicate: int? 
:clojure.spec/args ("Fred" "3") 
:clojure.spec/failure :instrument 
:clojure.spec.test/caller {:file "guide.clj", :line 709, :var-scope spec.examples.guide/eval3771} 

它不會是太難的宏defrecord和使用匹配規範構造的FDEF的組合。