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

欢迎!有关如何使用此页面的更多信息,请参阅关于页面.

+1
规格
截至1.9.0-alpha13,注册表中的规格缺少:文件元数据,尽管有:行,列


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}}' d的值上的元数据是不够的,因为在{{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

注意,当前的:line 和:line meta 这两个元数据并未指向规范定义的位置,而是指向了 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 报告)
...