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

欢迎!请在关于页面查看更多关于如何使用该网站的信息。

0
命名空间和变量
编辑

我在 dev/user.clj 中的这段代码启动时并没有运行,让我很惊讶。

(ns user) ; user ns is loaded by REPL startup

(println "Evaluating dev/user.clj")
(when-not (resolve 'xxx)
  (def xxx 1)
  (println "defing xxx"))

这对我有效。

(defonce yyy (let [tmp 1] (println (str "deffing yyy as " tmp))
                   tmp))

在 clojurians 上也有人建议这样做。
[https://clojurians.slack.com/archives/C053AK3F9/p1683882344251029][Slack]

(ns user)

(when-not (resolve 'xxx)
  (intern 'user 'xxx 42)
  (prn "!!!"))
这正是我在 dev/user.clj 中想完成的事情。

<pre><code>
(require '[portal.api :as portal])
(defonce p
  (let [tmp (portal/open)]
    (add-tap #'portal/submit)
    tmp))

</code></pre>
糟糕,我刚意识到这实际上并不能帮助解决多个门户窗口打开的问题。当我再次打开时,它们显然还是会打开。:-|

但是,语言问题仍然存在。

1 个答案

+1

在没有看到您完整的项目的情况下,我无法确定,但我猜测您的user命名空间被配置为进行AOT编译(在启动时将源代码编译成Java类,而不是从Clojure源代码编译)。在这种情况下,编译器经常优化可以在编译时执行而不是启动时执行的事情,因此您的println可能仅在项目编译时发生一次,而不是每次应用程序运行时都发生。这通常会让那些试图捕捉应用程序启动时间的人感到困惑;他们最终看到的是项目最后编译的时间。

理解顶层形式的生命周期可能很复杂和微妙,尤其是在编译和Clojure与JVM交互时。通过采用状态管理库,如Componentsystem,您可以避免与它们打交道,这是您可以从中获得的收益之一。

以下是我的deps.edn文件

https://github.com/jamiepratt/euler/blob/resolve/deps.edn

有关问题的代码位于dev/user.clj中,应该在我按下回车键时运行

https://github.com/jamiepratt/euler/blob/resolve/dev/user.clj

Calva使我能够将用于按下回车键的命令复制到剪贴板,下面是它

pushd /Users/jamiep/Documents/clj/euler ; clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version,"1.0.0"},cider/cider-nrepl {:mvn/version,"0.28.7"}}}' -M:dev:portal -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]" ; popd
啊,那么我们就让其他人来继续讨论吧,我仍然使用 Leiningen 作为我的 Clojure 构建器和启动器,所以我不了解在 deps.edn 世界中有什么是 AOT 编译的。
...