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)并重新开始。

我在classpath上有一些Clojure文件,需要不可用的依赖。这本身就让使用refresh变得不可能。

当使用set-refresh-dirs时,这个问题完全消失了。

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

这假设是对src、test下每个存在的命名空间都进行的良好假设。任意的工具可能在无法遵循这一既定标准的命名空间上崩溃。

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

by
为了明确起见,我欢迎任何提高生产力的方法,而且我恰好知道您所寻求的工作流程类型(因为当这个q在Clojurians Slack上分享时,我就在附近)。

如果进行t.n修改能够实现这一点,那就太好了!

但是,这个问题的表述过于假设,很容易留下误导性的信息线索,这就是为什么我想更好地反映为什么有些人可能会被迫按照tools.namespace的设计使用的原因。

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

我的解决方案修复了代码加载缓慢的问题。它仍然可以成功地保留自动化的代码**重**加载。

> 当使用set-refresh-dirs时,这个问题完全消失了。

如果这两个文件在同一个目录下,则问题根本不存在。
by
> 如果两个文件在同一目录下,它们根本没有被删除。

将不可加载的命名空间放在`src/`或`test/`下是不良的做法。这会直接影响到其他用户和工具。

如果您有不可加载的命名空间,最好将它们放在`examples/`、`drafts/`等目录下。
...