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 %)

哪个更清楚。

4

3 回答 3

7

这在以下 clojure 邮件列表线程中进行了讨论。

查看 clojure.core源代码,您可以看到 fn 宏仅将布尔值传递给 assert 函数,并且不包括用于传递附加消息参数的可选参数。

所以看起来还没有办法干净地做到这一点。

于 2013-06-30T17:14:09.467 回答
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)

返回

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!")  
于 2017-04-20T08:21:07.533 回答
2

扩展上述建议:

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

当您命名一个匿名函数时,涉及该 fn 的任何错误都将更具可读性

另外,你上面有两个%的替换是怎么回事?#() 不嵌套。

于 2013-07-01T01:11:47.037 回答