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 可能只在项目编译时发生一次,而不是每次运行应用程序时。这常常让那些试图在 var 中捕获应用程序启动时间的人感到困惑;他们最终看到的是项目最后一次编译的时间。

理解顶层形式的生命周期可能很棘手和微妙,尤其是当涉及到编译和 Clojure 与 JVM 之间的交互时。通过采用像 Componentsystem 这样的状态管理库,您不需要处理这些。

以下是我的 deps.edn

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

相关的代码位于 dev/user.clj 中,应在 jack in 时运行

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

Calva 允许我将它使用的 jack in 命令复制到剪贴板,如下所示

pushd /Users/jammiep/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编译。
...