2024 年 Clojure 状况调查! 中分享您的想法。

欢迎!请参阅 关于 页面了解更多关于此功能的信息。

+2
错误
当前在 {{:pre}} 或 {{:post}} 条件的列表中的一个谓词失败会导致类似以下的消息显示


(defn must-be-a-map [m] {:pre [(map? m)]} m)
(must-be-a-map [])
;;=> AssertionError 断言失败:)(map? m)  user/must-be-a-map (form-init.....clj:1)


通过允许将特定消息字符串与 {{:pre}} 和 {{:post}} 条件中的每个谓词关联起来,这些异常消息可以被显著提高描述性。

谓词函数及其相关消息字符串可以作为映射中的一个值对进行指定


(defn must-be-a-map
  [m]
  {:pre [{(map? m) "m 必须是一个映射,因为有一些特定的领域原因。"}]}
  m)


以下将生成如下错误消息

(must-be-a-map 10)
AssertionError 断言失败:由于某些特定的领域原因,m 必须是一个映射。
(map? m) user/must-be-a-map (form-init.....clj:1)


这将允许在指定未见消息的谓词的同时,根据相关的谓词消息对来进行


(defn n-and-m [n m] {:pre [(number? n) {(map? m) "您必须提供一个映射!"}]})


此更改不会破坏现有功能,并且仍然允许在代码的其他地方预定义谓词。

因此,前提和后续条件可以提供自然地记录函数来龙去脉的手段,简化在开发库时提供有意义的输出过程,并可能使语言更适合教学环境[1]

[1] http://wiki.science.ru.nl/tfpie/images/2/22/TFPIE2013_Steps_Towards_Teaching_Clojure.pdf

3 个回答

0
_由:coltnz_ 评论

所采用的方法不同于描述中推荐的方法,因为它不需要地图。现有的规范为

{:pre [pre-expr*]
 :post [post-expr*]}

实际上成为

{:pre [(pre-expr assert-msg?)*]
 :post [(pre-expr assert-msg?)*]}


其中 assert-msg 是一个字符串。注意这意味着在一个表达式之后的一个(可能是错误的)第二个字符串会被视为一个真的 pre-expr。

虚构示例

(defn print-if-alphas-and-nums [arg] {:pre [(hasAlpha arg) "No alphas"
                                            (hasNum arg) "No numbers"
                                            (canPrint arg)]}
  (println arg))

user=> (print-if-alphas-and-nums "a5%")
a5%
nil
user=> (print-if-alphas-and-nums "$$%")
AssertionError Assert failed: No alphas
(hasAlpha arg)  user/print-if-alphas-and-nums (NO_SOURCE_FILE:19)


我考虑过进一步扩展规范到(pre-expr assert-msg? data-map)*,这可能由 assert-info 中的 ex-info、 assert-data 的类似项支持来传达诊断信息(局部变量?)。地图可以包含一个:msg 键或地图可能是额外于消息字符串的。但在这个阶段我想等待输入。

我还考虑过允许在消息中允许与 fn 返回值相似的 % 替换,但在哪里进行转义?

 

0

评论者:coltnz

我应该指出,测试还包括目前未发现的现有功能。

0
参考:https://clojure.atlassian.net/browse/CLJ-1817(由 alex+import 报告)
...