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

欢迎!请查阅 关于 页面以获取更多关于其工作方式的信息。

0 投票
Clojure
重新标记

在较大的代码库和团队中,不同的人可能会对命名空间使用不同的别名进行 'require' 操作。

h.clj
(ns hello.core)

f.clj
(ns foo.core
    (:require [hello.core :as hc]))

b.clj
(ns bar.core
    (:require [hello.core :as h]))

如您所见,我参与过的的大型项目往往即使保持了一致性,同一命名空间也会出现不同的别名。这是人类缺陷,而且在大型团队中,这种情况经常失控。这使得使用简单的工具(如 grep)来查找命名空间及其内部的函数用法变得更难(例如在上面的情况下使用 hc/some-funch/some-func)。

我想提议的是,在 ns 宏本身中添加类似的功能

(ns hello.core :default-alias <my-alias>)

在需要此 ns 的地方

(ns foo.core 
    (:require [hello.core :default-alias])

我们可以自动获得 <my-alias> 指向命名空间,因此我们可以做 <my-alias>/some-func

这将导致在语言层面上强制执行的代码一致性
我相信这可以通过在命名空间中存储某种元数据来实现

2 个答案

+6 投票

被选中
 
最佳回答

您可以使用clj-kondo中的:consistent-alias代码检查器来强制执行这种一致性。

https://github.com/borkdude/clj-kondo/blob/master/doc/config.md#alias-consistency

太棒了!作为补充,clj-kondo是否可以支持用户配置?比如,我想设置跨项目的默认值,或者制定团队内部的规范?
用户配置不是按照设计原则支持的。您可以在这里阅读关于设计原则5的内容: https://github.com/borkdude/clj-kondo/blob/master/doc/dev.md
如果您认为这很重要,我建议您写一个小型的模板脚本/lein模板/clj新模板,以便直接复制您的配置。
+1

嗨,感谢您的建议,这是我之前没看到过的。

我认为这个提议的一个缺点是别名可能“从天而降”,这也有它自己的一类问题。我的意思是,这当然也是一种观点,但仅仅从特定的消费者命名空间来看,如果不找到和解决所有其他引用的命名空间,就无法了解别名指的是什么。

无论如何,我们并不想给ns宏或命名空间系统添加任何额外的复杂性,我认为我们不太可能添加这样的东西。

是的,我也担心了“无中生有”的问题:)

不管怎样,我会亲自尝试,至少是在我自己的Clojure分支上
这个提议还有其他问题

如果源命名空间因任何原因更改了默认别名,所有消费代码都会失效。

如果两个命名空间恰好有相同的默认别名,而且你尝试同时引用它们,你会遇到冲突。

任何依赖静态代码检查的工具都不会知道(hc/greet)是什么——现在,它们看到:as hc别名,并且可以在不加载命名空间的情况下“解析”hc/greet符号。
...