【发布时间】:2014-07-18 21:33:37
【问题描述】:
(defn string-to-string [s1]
{:pre [(string? s1)]
:post [(string? %)]}
s1)
我喜欢 :pre 和 :post 条件,它们让我可以更快地确定何时将“方钉放入圆孔中”。也许这是错误的,但我喜欢将它们用作一种可怜的男人类型检查器。但这不是哲学,这是一个简单的问题。
在上面的代码中,我似乎可以很容易地确定s1 是:pre 条件中的函数参数。同样,:post 条件中的% 始终是函数返回值。
我想要打印s1 或% 的值,当这些条件中的任何一个在 AssertionError 中失败时。所以我得到了类似的东西
(string-to-string 23)
AssertionError Assert failed: (string? s1)
(pr-str s1) => 23
AssertionError 包含一个用于标识为来自函数参数列表并在失败测试中引用的每个变量的单行。当函数的返回值不符合:post 条件时,我也想要类似的东西。
这将使在尝试从 AssertionError 进行诊断时快速发现我如何滥用函数变得微不足道。它至少会让我知道该值是 nil 还是实际值(这是我最常犯的错误)。
我有一些想法可以用宏来完成,但我想知道是否有任何安全和全局的方法来基本上重新定义 (defn 和 (fn 和朋友这样做 :pre 和 @ 987654335@ 还会打印导致测试失败的值。
【问题讨论】:
-
我可能遗漏了一些关于您的问题的内容,但是 try .. catch 是否允许在 :pre 或 :post 中使用?你不能这样报告问题吗?
-
我认为任何有效的形式都可以在 :pre 和 :post 中使用(虽然不确定)。我要指出 :pre 和 :post 中的形式似乎被插入到断言中。所以,你可以 (try (catch...)),但结果是 (assert (try (catch...)));没关系(虽然有点吵 & 也只能在实际断言之前打印)。不过,我的目标是实际修改底层 AssertError 本身,只需在 AssertionError 中添加相关符号和(pr-str 值)作为消息。
-
clojure 规范示例:clojure.org/guides/spec#_using_spec_for_validation
标签: clojure clojurescript