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>
糟糕,我刚刚意识到这实际上并不能帮助解决多个portal窗口打开的问题。在我重新连接到系统时,它们仍然会打开。:-|

但是语言问题仍然存在。

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