请在2024 Clojure状态调查!中分享您的想法。

欢迎!请查看关于页面以获取更多有关这如何工作的信息。

+1
规格
到1.9.0-alpha13版本为止,注册表中的规格缺少:file元数据,尽管有:line和:column。


user=> (require '[clojure.spec :as s])
user=> (-> (s/registry) (get :clojure.core.specs/arg-list) (meta))
{:line 1118, :column 5, :clojure.spec/name :clojure.core.specs/arg-list}
user=> (-> (s/registry) (get 'clojure.core/let) (meta))
{:line 1675, :column 5, :clojure.spec/name clojure.core/let}


这将是有用的,因为我们
* 我们可以通过过滤注册表列出一个项目中定义的所有规格。
* 我们可以读取规格的源,例如clojure.repl/source,用于美观格式化。

(特别是,用于Codox https://github.com/weavejester/codox/pull/134 )

我快速查看了一下,但没有看到设置元数据的地方。
加油

5 答案

0

评论人:alexmiller

顺便说一下,现在您可以使用s/describe或s/form来获取规格的源。

0
评论人:floybix

以下在我的测试中有效。(为了测试,我使用了{{in-ns}}, {{@#'registry-ref}}, {{#'ns-qualify}}))。

方法是设置def之后的注册项元数据。仅仅在{{def}}定义的值上设置元数据是不够的,因为它随后在{{def}}内部被修改。


(ns clojure.spec)
(alias 'c 'clojure.core)

(defmacro def
  [k spec-form]
  (let [k (if (symbol? k) (ns-qualify k) k)
        m (assoc (meta &form) :file *file*)]
    `(do
       (def-impl '~k '~(res spec-form) ~spec-form)
       (swap! registry-ref update '~k vary-meta c/merge ~m)
       '~k)))

(defmacro fdef
  [fn-sym & specs]
  (let [k (ns-qualify fn-sym)
        m (assoc (meta &form) :file *file*)]
    `(do
       (clojure.spec/def ~fn-sym (clojure.spec/fspec ~@specs))
       (swap! registry-ref update '~k vary-meta c/merge ~m)
       '~k)))




顺便说一下,现在您可以使用s/describe或s/form来获取规格的源。


是的,这很不错,但规格较长时,换行和缩进很有帮助。
0

评论作者:wagjo

注意,当前的:行和:列元数据并没有指向规格定义的位置,而是指向clojure/spec.clj文件,例如第二个例子(c.c/let)指向(链接: https://github.com/clojure/clojure/blob/c0326d2386dd1227f35f46f1c75a8f87e2e93076/src/clj/clojure/spec.clj#L1675 文本:fspec-impl)

0
_评论作者:martinklepsch_

我一直致力于解决这个问题,对于不是 {{ident?}} 的规格,我们可以使用元数据或描述 {{regex?}} 规格的映射。

对于 {{ident?}} 规格,我不确定如何处理额外的数据 - 它可以存储在注册表的另一个位置,这可能是一条可行的路径。

使用任何这些方法,我将不清楚如何以一致的方式将此信息集成到返回值{{get-spec}}中,因为它的返回值可能不是映射(因此不可扩展。)

将它们存储在注册表的另一个位置,如前所述,但那样我们可能需要一个或多个函数或协议方法来获取有关源文件/行的信息。

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