Error handling Clojure:在分解结构时预报告失败值

Error handling Clojure:在分解结构时预报告失败值,error-handling,clojure,preconditions,Error Handling,Clojure,Preconditions,接下来,我想在函数中打印前提条件的值。但是,在以下情况下(可能是解构),它会失败: 我有一个dir?helper函数(可以跳过此函数): 它工作得很好,使用is宏,我得到了一些很好的错误消息,我可以看到测试和通过的参数: (is (dir? (io/file "resources/static"))) ;; => true (is (dir? (io/file "resources/statice"))) ;; typo, error below 在clojure.lang.Persi

接下来,我想在函数中打印前提条件的值。但是,在以下情况下(可能是解构),它会失败:

我有一个
dir?
helper函数(可以跳过此函数):

它工作得很好,使用
is
宏,我得到了一些很好的错误消息,我可以看到测试和通过的参数:

(is (dir? (io/file "resources/static"))) ;; => true

(is (dir? (io/file "resources/statice"))) ;; typo, error below
在clojure.lang.PersistentList中失败$EmptyList@1 (boot.user4515592986834245937.clj:86)应为:(dir?(io/file) “资源/静态”))实际:(非(dir?#对象[java.io.File 0x6730a420“资源/静态”])

但是,当尝试在前提条件
:pre
中使用它时,我遇到了一个可怕的错误:

(defn make-something
  [&{:keys [dir]
     :or {dir "default-dir"}}]
  {:pre [(is (dir? (clojure.java.io/file dir)))]}
  ;;... do something with these
 )

(make-something :dir "resources/statices") ;; doesn't exist
clojure.lang.Compiler$CompilerException:java.lang.AssertionError: 断言失败:(is(dir?(io/file dir)), 编译:(boot.user4515592986834245937.clj:80:12) 断言错误:断言失败:(is(dir?(io/file dir)))

我怎样才能在我的函数中得到一个好的错误消息,就像上面的一样


如果有问题,我正在使用Clojure 1.7。

您需要检查代码(
dir?
函数)。以下代码片段适合我:

(require '[clojure.java.io :as io])

(defn dir? [s]
  (let [dir (io/file s)]
    (and (.exists dir)
         (.isDirectory dir))))

(defn make-something
  [& {:keys [dir] :or {dir "default-dir"}}]
  {:pre [(is (dir? dir))]}
  (println dir))

(make-something :dir "/tmp")
out => /tmp
ret => nil

(make-something :dir "/xxxx")
FAIL in clojure.lang.PersistentList$EmptyList@1 (form-init3332271312167175068.clj:1)
expected: (dir? dir)
actual: (not (dir? "/xxxx"))

AssertionError Assert failed: (is (dir? dir))  user/make-sth (form-init3332271312167175068.clj:1)

“nice”错误消息应在标准输出中打印。memfn在clojure 1.0之前已被去除润滑,#(.isDirectory…)表单更正常now@ArthurUlfeldt哦,有意思,我哪儿都没看到。你从哪里得到的信息?它不在源代码中,这是因为我在Arthur的评论之后手工编辑了代码。您的代码现在可以在我的REPL中运行,所以我接受了您的答案(尽管Clojure 1.8—我还没有像最初的问题中那样使用1.7进行测试)。
(require '[clojure.java.io :as io])

(defn dir? [s]
  (let [dir (io/file s)]
    (and (.exists dir)
         (.isDirectory dir))))

(defn make-something
  [& {:keys [dir] :or {dir "default-dir"}}]
  {:pre [(is (dir? dir))]}
  (println dir))

(make-something :dir "/tmp")
out => /tmp
ret => nil

(make-something :dir "/xxxx")
FAIL in clojure.lang.PersistentList$EmptyList@1 (form-init3332271312167175068.clj:1)
expected: (dir? dir)
actual: (not (dir? "/xxxx"))

AssertionError Assert failed: (is (dir? dir))  user/make-sth (form-init3332271312167175068.clj:1)