2013-06-30 12 views
8

Ho questo (not (some #(= (:length %1) 0) %)) come post-condizione. Scritto in questo modo è abbastanza chiaro, ma quando questa condizione non viene soddisfatta ottengo questo:Posso includere un messaggio in pre e post-condizioni

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

Quale non è molto leggibile. C'è un modo per definire il messaggio per una postcondizione o per una precondizione?

Edit 1:

seguito noahlz e suggestione noisesmiths, (ma utilizzando una funzione denominata esterna):

(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})) 

dà:

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

Che è alot più chiara.

risposta

7

Questo è discusso nella seguente mailing list di clojure thread.

Guardando il clojure.core source si può vedere la macro fn passa solo in un valore booleano alla funzione di affermare, e non include un parametro opzionale per il passaggio di un ulteriore argomento messaggio.

così sembra non c'è ancora modo di farlo in modo pulito.

+0

Quel filo è di due anni e mezzo di età, e non è stato commentato da chiunque con qualsiasi potere decisionale. Non direi che questa funzione è stata considerata per l'inclusione. – amalloy

+0

Sembra che la soluzione non sia l'uso di nomi di funzioni più descrittivi nei propri asserti (non funzioni inline). – noahlz

+0

Risposta aggiornata per riflettere cosa ha notato amalloy. –

2

espandendo su un suggerimento sopra:

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

quando è il nome di una funzione anonima, eventuali errori che coinvolgono che fn sarà più leggibile

anche, come è possibile che si dispone di due% sostituzioni di cui sopra? #() non nidifica.

+0

% in una post-condizione fornisce il valore di ritorno della funzione. Un'altra ragione per usare '(fn ...)' invece di '# (...)' Suppongo. – snowape

2

Questo post nello stesso thread suggerisce l'uso di clojure.test/is macro, che restituisce un messaggio di errore significativo.

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

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

(get-key [] 0) 

rendimenti

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!") 
Problemi correlati