所以,我越来越深入地研究Clojure.Spec。
我偶然发现的一件事是,将我的规范放在哪里。我认为有三种选择:
全局规格文件
在大多数例子中,我在网上发现,有一个大的spec.clj文件,在主名称空间中是必需的。它拥有所有“数据类型”和函数的所有(s/def)和(s/fdef)。
专业:
Contra:
产品名称空间中的规范
您可以将(s/def)和(s/fdef)放在产品代码旁边。因此,实现和规范在同一个名称空间中共存。
专业:
Contra:
专用规范命名空间结构
然后我想,也许规范是第三种代码(除了生产和测试)。所以也许他们应该拥有自己的命名空间结构,就像这样:
├─ src
│ └─ package
│ ├─ a.clj
│ └─ b.clj
├─ test
│ └─ package
│ ├─ a_test.clj
│ └─ b_test.clj
└─ spec
└─ package
├─ a_spec.clj
└─ b_spec.clj专业:
Contra:
谁有其中一种方法的经验?
还有别的选择吗?
你对不同的选择有什么看法?
发布于 2016-06-21 13:27:05
我通常将规范放在它们自己的名称空间中,并与它们描述的名称空间一起使用。只要他们使用一致的命名约定,他们的名字就不重要了。例如,如果我的代码在my.app.foo中,我将把规范放在my.app.foo.specs中。
规范键名最好位于代码的名称空间中,而不是规范的名称空间中。通过在关键字上使用名称空间别名仍然很容易做到这一点:
(ns my.app.foo.specs
(:require [my.app.foo :as f]))
(s/def ::f/name string?)我不想把所有的东西都放在一个巨大的规范名称空间中(真是个噩梦)。虽然我当然可以将它们与规范代码放在同一个文件中,但这损害了我的可读性。
您可以将所有规范名称空间放在单独的源路径中,但这样做并没有真正的好处,除非您想分发代码,而不是分发规范,反之亦然。很难想象那会是什么。
发布于 2017-01-04 10:43:47
在我看来,规范应该与代码位于相同的ns中。
我主要考虑的是我的个人哲学,从技术上讲,它效果很好。我的哲学是,功能的规范是它不可分割的一部分。这不是什么额外的事情。这绝对不是OP中提到的“两个问题”。实际上,它就是函数,因为在正确性方面:谁在乎实现呢?谁在乎你在你的defn里写了什么?谁在乎标识符?除了规格谁还在乎什么?
我认为这很奇怪,因为不仅clojure.spec是后来出现的,而且大多数语言都不允许将规范作为一个整体,即使您希望它是一个完整的东西,而且任何接近的东西(可能是代码中的测试)通常都是不允许的,所以这当然看起来很奇怪。但是仔细想想,你可能会像我一样得出一个结论(或者你可能不会,这部分是固执己见的)。
关于为什么您不希望在相同的ns中使用规范,我能想到的唯一好的理由是以下两个原因:
至于第一个原因,嗯,再次,我认为这是你的功能的一个组成部分。如果您发现它真的太多了,我的建议将是一样的,如果您的ns会太混乱,不管规格:看看你是否可以把它分开。
至于第二个原因,如果您真的关心,您可以签入代码,如果clojure.spec ns是可用的,如果没有,那么就用NOP函数/宏隐藏名称。另一种选择是使用clojure-未来-规范,但我自己还没有尝试过,所以我不知道它的工作效果如何。
另一种在技术上很好的解决方法是,有时存在一个循环依赖关系,您无法处理不同的名称空间,例如,当您的规范依赖于您的代码(函数规范),而您的代码依赖于您的规范进行解析时(请参阅此问题)。
发布于 2016-06-21 22:45:17
另一个考虑因素取决于您的用例--将规范与您的主要代码放在一起,将您的代码限制到Clojure 1.9客户端,这可能是您想要的,也可能不是您想要的。与@levand一样,我建议为您的每个代码命名空间设置一个并行命名空间。
https://stackoverflow.com/questions/37942495
复制相似问题