Clojure.spec - 为什么有用,什么时候用
Clojure.spec - Why is it useful and when is it used
我最近看了Rich Hickeys talk at Cojure Conj 2016,虽然很有趣,但我并没有真正理解clojure.spec
中的要点,也不知道你什么时候用它。似乎大多数想法,例如 conform、valid 等,在 Clojure 中已经具有类似的功能。
我现在只学习 clojure 大约 3 个月所以这可能是由于缺乏 programming/Clojure 经验。
clojure.spec 和 cljs.spec 的工作方式与 Clojure 和 Cljs 相似,尽管它们并非 100% 相同,但它们基于相同的基本原则。
- 您是否厌倦了编写程序文档?
- 补考的前景是否会导致拖延?
- 当老板说"test coverage"的时候,你会害怕吗?
- 您是否忘记了数据名称的含义?
为了顺利表达硬规格,需要Clojure.Spec!
Clojure.spec 为您提供了一种统一的方法来记录、指定和自动测试您的程序,并验证您的实时数据。
它几乎窃取了它的每一个想法。它不会做任何你不能为自己做的事情。
但在我几乎不了解的情况下,它改变了规范的经济性,使它值得正确地做。改变游戏规则? - 很有可能。
在上周的 clojure/conj 会议上,可能有一半的演示文稿以某种方式介绍了规范,而且它甚至还没有结束 alpha。 spec 是 clojure 的 主要 特性;它就在这里,而且功能强大。
以静态类型检查为例,它被许多人誉为一种安全网,也是许多编程语言的定义特征。它的局限性非常大,因为它只擅长编译时,而且它只检查类型。另一方面,spec 验证并符合 args return 的任何谓词(不仅仅是类型),并且还可以验证 relationships两者之间。所有这些都在函数代码的外部,将函数的逻辑与代码的验证和文档分开。
关于工作流程:
relationship-checking 相对于仅 type-checking 的优势的一个典型示例是计算字符串子字符串的函数。类型检查确保 (subs s start end)
中的 s
是字符串,而 start
和 end
是整数。但是,必须在函数内进行额外的检查以确保 start
和 end
是正整数,end
大于 start
,并且结果子字符串不是比原来的字符串大。例如,所有这些东西都可以指定(如果其中一些有点多余甚至不准确,请原谅我):
(s/fdef clojure.core/subs
:args (s/and (s/cat :s string? :start nat-int? :end (s/? nat-int?))
(fn [{:keys [s start end]}]
(if end
(<= 0 start end (count s))
(<= 0 start (count s)))))
:ret string?
:fn (fn [{{:keys [s start end]} :args, substring :ret}]
(and (if end
(= (- end start) (count substring))
(= (- (count s) start) (count substring)))
(<= (count substring) (count s)))))
使用满足上述args
规范的示例数据调用函数:
(s/exercise-fn `subs)
或 运行 1000 次测试(这可能会失败几次,但保持 运行ning 并且它会起作用——这是由于 built-in 生成器无法满足 :args
谓词的第二部分;如果需要,可以编写自定义生成器):
(stest/check `subs)
或者,想实时查看您的应用是否在 运行 期间对 subs
进行了无效调用?只是 运行 这个,如果函数被调用但不符合规范,你会得到一个规范异常:
(stest/instrument `subs)
我们还没有将其集成到我们的工作流程中,并且不能投入生产,因为它仍处于 alpha 阶段,但首要目标是编写规范。我将它们放在同一个命名空间中,但目前放在不同的文件中。
我预见我们的工作流程是 运行 使用这个(在 clojure 规范指南中找到)对规范函数的测试:
(-> (stest/enumerate-namespace 'user) stest/check)
然后,最好打开所有功能的检测,运行 应用程序在负载下,我们通常会对其进行测试,并确保 "real world" 数据正常工作。
您还可以使用 s/conform
在函数本身中解构复杂数据,或使用 s/valid
作为 运行ning 函数的前置条件和 post- 条件。我不太喜欢这个,因为它在生产系统中是开销,但这是可能的。
没有极限,我们才刚刚触及表面!在接下来的几个月和几年里,规格将会很酷!
我最近看了Rich Hickeys talk at Cojure Conj 2016,虽然很有趣,但我并没有真正理解clojure.spec
中的要点,也不知道你什么时候用它。似乎大多数想法,例如 conform、valid 等,在 Clojure 中已经具有类似的功能。
我现在只学习 clojure 大约 3 个月所以这可能是由于缺乏 programming/Clojure 经验。
clojure.spec 和 cljs.spec 的工作方式与 Clojure 和 Cljs 相似,尽管它们并非 100% 相同,但它们基于相同的基本原则。
- 您是否厌倦了编写程序文档?
- 补考的前景是否会导致拖延?
- 当老板说"test coverage"的时候,你会害怕吗?
- 您是否忘记了数据名称的含义?
为了顺利表达硬规格,需要Clojure.Spec!
Clojure.spec 为您提供了一种统一的方法来记录、指定和自动测试您的程序,并验证您的实时数据。
它几乎窃取了它的每一个想法。它不会做任何你不能为自己做的事情。
但在我几乎不了解的情况下,它改变了规范的经济性,使它值得正确地做。改变游戏规则? - 很有可能。
在上周的 clojure/conj 会议上,可能有一半的演示文稿以某种方式介绍了规范,而且它甚至还没有结束 alpha。 spec 是 clojure 的 主要 特性;它就在这里,而且功能强大。
以静态类型检查为例,它被许多人誉为一种安全网,也是许多编程语言的定义特征。它的局限性非常大,因为它只擅长编译时,而且它只检查类型。另一方面,spec 验证并符合 args return 的任何谓词(不仅仅是类型),并且还可以验证 relationships两者之间。所有这些都在函数代码的外部,将函数的逻辑与代码的验证和文档分开。
关于工作流程:
relationship-checking 相对于仅 type-checking 的优势的一个典型示例是计算字符串子字符串的函数。类型检查确保 (subs s start end)
中的 s
是字符串,而 start
和 end
是整数。但是,必须在函数内进行额外的检查以确保 start
和 end
是正整数,end
大于 start
,并且结果子字符串不是比原来的字符串大。例如,所有这些东西都可以指定(如果其中一些有点多余甚至不准确,请原谅我):
(s/fdef clojure.core/subs
:args (s/and (s/cat :s string? :start nat-int? :end (s/? nat-int?))
(fn [{:keys [s start end]}]
(if end
(<= 0 start end (count s))
(<= 0 start (count s)))))
:ret string?
:fn (fn [{{:keys [s start end]} :args, substring :ret}]
(and (if end
(= (- end start) (count substring))
(= (- (count s) start) (count substring)))
(<= (count substring) (count s)))))
使用满足上述args
规范的示例数据调用函数:
(s/exercise-fn `subs)
或 运行 1000 次测试(这可能会失败几次,但保持 运行ning 并且它会起作用——这是由于 built-in 生成器无法满足 :args
谓词的第二部分;如果需要,可以编写自定义生成器):
(stest/check `subs)
或者,想实时查看您的应用是否在 运行 期间对 subs
进行了无效调用?只是 运行 这个,如果函数被调用但不符合规范,你会得到一个规范异常:
(stest/instrument `subs)
我们还没有将其集成到我们的工作流程中,并且不能投入生产,因为它仍处于 alpha 阶段,但首要目标是编写规范。我将它们放在同一个命名空间中,但目前放在不同的文件中。
我预见我们的工作流程是 运行 使用这个(在 clojure 规范指南中找到)对规范函数的测试:
(-> (stest/enumerate-namespace 'user) stest/check)
然后,最好打开所有功能的检测,运行 应用程序在负载下,我们通常会对其进行测试,并确保 "real world" 数据正常工作。
您还可以使用 s/conform
在函数本身中解构复杂数据,或使用 s/valid
作为 运行ning 函数的前置条件和 post- 条件。我不太喜欢这个,因为它在生产系统中是开销,但这是可能的。
没有极限,我们才刚刚触及表面!在接下来的几个月和几年里,规格将会很酷!