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

欢迎!请查看 关于 页面,了解更多关于它是如何工作的信息。

+12
tools.namespace

当前 clojure.tools.namespace.repl/refresh 实现中的两个问题

  1. 在首次调用时,它会重新加载 classpath 上的所有 Clojure 文件。其文档字符串暗示了这一点,但没有解释为什么需要这种行为。至少,它使第一次 refresh 调用比所需的要慢得多。

  2. 它甚至会尝试重新加载之前未加载的文件。这是一个非常真实的情况 - 我有一些位于 classpath 上的 Clojure 文件,它们需要一些不可用的依赖项。这本身就使得使用 refresh 成为不可能。也许,它可以修改为避免加载之前未加载的文件。

目前,我使用以下解决方案

(alter-var-root #'clojure.tools.namespace.repl/refresh-tracker
                assoc :clojure.tools.namespace.dir/time (System/currentTimeMillis))

(alter-var-root #'clojure.tools.namespace.repl/remove-disabled
                (fn [orig-remove-disabled]
                  (fn [tracker]
                    (let [filter-loaded #(filter find-ns %)]
                      (-> tracker
                          orig-remove-disabled
                          (update :clojure.tools.namespace.track/unload filter-loaded)
                          (update :clojure.tools.namespace.track/load filter-loaded))))))

当然,该解决方案假设每个文件都有一个合适的 ns 表达式,并且不会创建其他命名空间。但似乎这也被 tools.namespace 采用了,尤其是通过使用 clojure.tools.namespace.file/read-file-ns-decl

1 个答案

+1

在首次调用时,它会重新加载 classpath 上的所有 Clojure 文件。

更正:它不会重新加载 classpath 上的任何 ns。它受限于目录(与包含在 .jar 文件中的 .clj 文件不同,它们也构成了 classpath 的一部分)。

无论如何,这是当用户未执行 set-refresh-dirs 时的行为。tools.namespace 无法最好地猜测 refresh-dirs 的值,因此最佳做法是在事先有意地设置它。

这在 Sierra 的 reloaded 模板中得到了体现。

至少,它会使得第一次刷新调用比所需的慢很多。

tools.namespace 针对寻求自动化代码重新加载和面向项目工作流程的程序员。

它假设您想 使用您的项目(与任意脚本集相比),无法猜测哪个项目命名空间将是第一个必要的,或者您首先会做什么(运行测试、启动服务器?)。因此,它会加载每个命名空间。

值得注意的是,REPL 会话可以持续数天,甚至数周。如果出现问题,您可以使用 (clear) 开始重新。

我在类路径上有一些 Clojure 文件,需要一些不可用的新依赖。仅这一点就使 refresh 无法使用。

使用 set-refresh-dirs 时,此问题不复存在。

当然,此解决方案假设每个文件都有一个合适的 ns 表单,并且不会创建其他命名空间。

这是一个很好的假设,尽管对于每个位于 src 或 test 下的 ns 都是如此。任意工具在无法遵循这一既定标准时可能会失效。

再次强调,这是 set-refresh-dirs 存在的原因 - 为了区分主源路径(如 src/test/)和其他包含示例、脚本、草案等内容的目录。在给定的项目中,对任意命名空间执行 require 实际上是危险的(因为这些可能是面向生产的脚本等等)。

by
为了清楚起见,我欢迎所有提高生产力的方法,事实上我知道您在寻求什么样的工作流程(因为我当时参与了 Clojurians Slack 中关于此问题的讨论)。

如果执行 t.n 修改能够实现这一目标,那太好了!

但这个问题的提出过度假设,并且可能会留下错误的信息线索,这就是为什么我想更好地反映为什么有些人可能会被说服使用工具 namespace 以其设计的方式。

您可能可以在 Sierra 的写作或演讲中找到更多关于 t.n 逻辑的信息。
by
> tools.namespace 针对寻求自动化代码重新加载和面向项目工作流程的程序员。

我的解决方案解决了代码加载缓慢的问题。同时,它还能正常运行自动化的代码**重新**加载功能。

> 使用 set-refresh-dirs 时,此问题不复存在。

如果两个文件位于同一目录,此问题根本不会消失。
> 如果两个文件在同一目录下,则并未完全删除。

将无法加载的命名空间放置在 `src/` 或 `test/` 下是一种不好的实践。它将直接影响其他用户和工具。

如果存在无法加载的命名空间,最好将它们放置在 `examples/`、`drafts/` 等目录下。
...