我可以在前置条件和后置条件中包含消息

sno*_*ape 8 error-handling clojure

我有这个(not (some #(= (:length %1) 0) %))作为后置条件.写得这样很清楚,但是如果不满足这个条件,我得到这个:

Assert failed: (not (some (fn* [p1__17852#] (= (:length p1__17852#) 0)) %))
Run Code Online (Sandbox Code Playgroud)

哪个不太可读.有没有办法为后置条件或前置条件定义消息?

编辑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}))
Run Code Online (Sandbox Code Playgroud)

得到:

AssertionError Assert failed: (not-zero-length %)
Run Code Online (Sandbox Code Playgroud)

哪个更清楚.

O.P*_*ell 7

这将在以下clojure邮件列表线程中讨论.

查看clojure.core 源代码,您可以看到fn宏只将一个布尔值传递给assert函数,并且不包含用于传递其他消息参数的可选参数.

所以看起来没有办法干净利落地做到这一点.


sha*_*8me 6

同一线程中的这篇文章建议使用 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)
Run Code Online (Sandbox Code Playgroud)

返回

FAIL in clojure.lang.PersistentList$EmptyList@1 (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!")  
Run Code Online (Sandbox Code Playgroud)