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 に関連するエラーが読みやすくなります

また、上記の % 置換が 2 つあるのはどうしてですか? #() はネストしません。

于 2013-07-01T01:11:47.037 に答える