我刚开始学习 Clojure 和 Emacs。我已经让 Clojure Box for windows 运行,我希望能够在缓冲区中编写代码,然后在 REPL 中运行它而无需调用
(use 'example.code)
每时每刻。我知道 Cc Ck 但它不会重新加载命名空间。如果我使用
(in-ns 'example.code)
在它工作的 repl 中更改命名空间。这样做的正确方法是什么?
我刚开始学习 Clojure 和 Emacs。我已经让 Clojure Box for windows 运行,我希望能够在缓冲区中编写代码,然后在 REPL 中运行它而无需调用
(use 'example.code)
每时每刻。我知道 Cc Ck 但它不会重新加载命名空间。如果我使用
(in-ns 'example.code)
在它工作的 repl 中更改命名空间。这样做的正确方法是什么?
in-ns
是正确的方法之一。
对我来说最“正确”的方式是在 REPL(require '[example.code :as ec])
的命名空间中工作;user
这样我的一次性实验状态就保持不变user
并且ec/foo
对我来说足够方便(并且它很明显foo
应该来自哪里)。你总是可以说(require :reload-all 'example.code)
(同样适用于use
)来强制重新编译。
此外,这是一个删除(从当前命名空间)从给定命名空间中提取的所有映射的函数use
:
(defn unuse [ns]
(doseq [[n v] (ns-refers *ns*)]
(if (= (.. v ns name) ns)
(ns-unmap *ns* n))))
最重要的是,您可以构建
(defn reuse [ns]
(unuse ns)
(remove-ns ns)
(use :reload-all ns))
并说(reuse 'example.code)
要让你的命名空间接近一个新的开始。(请注意,1.2 的新功能,例如deftype
&defrecord
引入了一些复杂性......特别是unuse
对import
ed 类没有影响——这包括记录和deftype
-created 类型。:reload-all
仍然会导致deftype
et al. 重新编译表单,但我记得很奇怪这似乎还不够的情况......可能是我的错误,可能是我尚未完全探索的这些功能的一些神秘方面。)
也许“肮脏”的方式只是使用 (ns 'example.code) 切换到 repl 中缓冲区的名称空间。肮脏的原因是您将缓冲区定义与 repl 定义混合在一起。我认为 Marczyk 的答案是正确的。