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

欢迎!请查看关于页面了解更多关于这个工作方式的信息。

0
Clojure
(def a)会破坏#'a元数据,请检查这个


(def ^:mykey a 1)

(meta #'a)              ;; sx, :mykey 存在

(let [v (def a)]
  [(meta v)            ;; 未存在 :mykey,元数据已破坏
    (identical? v #'a)  ;; true,我们谈论的是同一个变量
   ])

(meta #'a)              ;; 未存在 :mykey


如果这不是一个错误而是一个“功能”,那么我们至少有两个问题

1- def 特殊形式文档根本未说明这种行为,需要澄清。根据现有文档,似乎进行带有无初始化的 def 不会产生任何副作用,但这并不适用于变量元数据。

2- defmulti 使用此形式查找变量并检查它是否已绑定到 MultiFn,如果是这样的话,那么 defmulti 什么也不做...但实际上它做了,在所谓的非破坏性检查中,defmulti 会破坏原始变量的元数据。这是相关的 defmulti 代码片段


(let [v# (def ~mm-name)]
  (when-not (and (.hasRoot v#) (instance? clojure.lang.MultiFn (deref v#))))
   ...

6 答案

0
by

评论由:alexmiller

我认为这主要是 CLJ-1148 的重复,但我将把它留在这里,因为它更具体地说明了具体问题。

0
by

评论由:nahuel

亚历克斯·米勒:CLJ-1148似乎是一个特例,这个问题在这里出现,但CLJ-1148中的补丁仅解决{{defonce}}的问题,而不是一般性的{{def}},也不是针对{{defmulti}}的,并且在{{def}}特殊形式文档中没有对此行为进行说明。

0
by

评论由:stu 发布

我相当确定我们以前在这里讨论过,并决定{{def}}的作用是符合预期的。(如果有人能找到线程/工单,请添加链接。)我认为这应该是一个文档增强。

如果{{defmethod}}的行为是单独的缺陷,请为该问题创建单独的工单,并演示一个示例问题。

0
by

评论由:jafingerhut 发布

CLJ-1213可能相关,但它没有提及元数据,只有(def foo)没有提供初始化值。

0
by

评论由:seancorfield 发布

如果Stuart是对的,这部分是{{def}}的“正确”行为,那么{{defonce}}不应该使用(def ~name) —— 如CLJ-1148所述。我们能否一劳永逸地作出决定,如果行为按设计进行,就拒绝这个问题?或者我们想要一个补丁来更新文档字符串,使元数据问题清晰可见?

0
by
参考: https://clojure.atlassian.net/browse/CLJ-1446(由nahuel报告)
...