http://clojure.org/special_forms документирует, что карта условий для fn
(таким образом также defn
) должна иметь форму:
{:pre [pre-expr*]
:post [post-expr*]}
{:post (number? %)}
приведет к (number? %)
рассматривается как последовательность утверждений, что означает, что оно интерпретируется как два отдельных утверждения: number?
и %
.
user> (macroexpand-1 '(fn [a] {:post (number? %)} a))
(fn*
([a]
(clojure.core/let [% a]
(clojure.core/assert number?)
(clojure.core/assert %)
%)))
(assert number?)
всегда проходит, пока number?
определено и имеетистинное значение, которое является основной функцией, вероятно, так и есть.(clojure.core/assert %)
проходит, если %
имеет истинное значение.Он связан со значением вашего аргумента a
через let
, поэтому он проходит, если a
имеет истинное значение.Попробуйте вызвать (my-post nil)
с вашим первым определением функции, и оно не будет подтверждено.
user> (my-post nil)
; Evaluation aborted.
; Assert failed: %
; [Thrown class java.lang.AssertionError]
Если вы правильно поместите свое постусловие в вектор, оно расширится так: