2013-06-30 30 views
8

我有這個(not (some #(= (:length %1) 0) %))作爲後置條件。這樣寫的,很明顯,但是當這個條件不能滿足我得到這個:我可否在前置和後置條件中包含消息

Assert failed: (not (some (fn* [p1__17852#] (= (:length p1__17852#) 0)) %)) 

這是不是很可讀。有沒有辦法爲後置條件或前提條件定義消息?

編輯1:

繼noahlz和noisesmiths建議,(但使用外部命名功能):

(defn not-zero-length 
    [evseq] 
    (not (some (fn [item] (= (:length item) 0)) evseq))) 

(defn my-func 
    [evseq] 
    {:post [(not-zero-length %)]} 
    evseq) 

(my-func '({:length 3}{:length 0})) 

給出:

AssertionError Assert failed: (not-zero-length %) 

這是很多更清晰。

回答

7

這在以下clojure郵件列表thread中討論。

縱觀clojure.core source可以看到FN宏只傳遞一個布爾值,斷言功能,並且不包括一個可選的參數傳遞一個附加消息參數英寸

所以它看起來像沒有辦法乾淨地做這件事。

+0

該線程是兩年半了,而不是由任何決策權的人評論。我不會說這個功能正在考慮列入。 – amalloy

+0

似乎解決方案是不在斷言中使用更多的描述性函數名稱(不是內聯函數)。 – noahlz

+0

已更新答案,以反映amalloy提到的內容。 –

2

擴展上面一個建議:

(not (some (fn zero-length [item] (= (:length item) 0)) %)) 

當你的名字匿名函數,涉及該FN任何錯誤都將更具可讀性

也,是什麼讓你有以上兩種%替換? #()不嵌套。

+0

%在後置條件下給出函數的返回值。使用'(fn ...)'而不是'#(...)'的另一個原因我想。 – snowape

2

這個post在同一個線程中建議使用clojure.test/is宏,它會返回一個有意義的錯誤信息。

(require '[clojure.test :refer [is]]) 

(defn get-key [m k] 
    {:pre [(is (map? m) "m is not a map!")]} 
    (m k)) 

(get-key [] 0) 

回報

FAIL in [email protected] (form-init8401797809408331100.clj:2) 
m is not a map! 
expected: (map? m) 
    actual: (not (map? [])) 
AssertionError Assert failed: (is (map? m) "m is not a map!") 
相關問題