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

欢迎!请参阅关于页面,了解更多有关本站运作的信息。

+1
Spec
截至1.9.0-alpha13,注册表中的spec缺少: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}


这会有帮助,因为
* 我们可以通过过滤注册表列出项目中定义的所有spec。
* 我们可以像clojure.repl/source一样阅读spec的源代码,以便进行美观格式化。

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

我快速查看了一下,但看不到在哪里设置了元数据。
问候

5 个答案

0

由:alexmiller发表的评论

顺便说一下,你现在可以使用s/describe或s/form来获取spec的源代码。

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来获取spec的源代码。


是的,这很棒,只是在较长的规范中,当需要换行和缩进时除外。
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报告)
...