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 窗口打开的问题。当我在 rejack 重新登录时,这些窗口显然还是会打开。:-|

但语言问题仍存在。

1 个答案

+1

在没有看到你的完整项目的情况下,我不能确定,但我猜测你的user命名空间被配置为预编译(在启动时间之前编译为Java类,而不是在启动时从Clojure源代码编译)。在这种情况下,编译器通常会优化在编译时而不是在启动时可以执行的操作,因此你的println可能在项目编译时只发生一次,而不是每次运行应用程序时都发生。这常常会给试图做诸如在变量中捕获应用程序启动时间的人带来麻烦;他们最终看到的只是项目编译的最新时间。

理解顶层形式的生命周期可能非常棘手且微妙,尤其是当涉及到编译以及Clojure与JVM之间的交互时。通过采用像Componentsystem这样的状态管理库,你可以避免与这些问题纠缠,这是你可以从中获得的一个好处。

以下是我的deps.edn

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

有关代码在dev/user.clj中,并且让我运行jack时应该运行

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