Clojure名称空间管理 - 是否有办法保存和恢复Clojure Repl名称空间,导入等的状态?
-
28-09-2019 - |
题
Clojure具有大量功能/宏,用于使用名称空间和Java软件包导入。对于我的(有限),理解命名空间的设置可以在Clojure过程(repl)中视为状态。
在REPP会话中迭代工作时,尤其是当源文件(RE)加载时,我可以很容易地感到困惑 - 通常是在命名空间配置中犯错或语法错误时。其他时候,我想尝试重构名称空间/别名/参考过滤器,但不能轻易退出现有的名称空间状态,而无需重新启动重置。
例如,我希望能够检查点命名空间配置 - 例如,在重新加载代码的主体之后 - 然后在尝试在REPP中导入的一些库后,请返回到该“清洁式封闭”,以便我可以立即测试一个源文件,该文件作为NS宏的一部分导入该库中过滤的方法。
人们可以推荐保存和恢复名称空间配置的方法吗?
解决方案
我确定有 某物 这是错误的,因为我刚刚回答了这个问题,但我可以肯定地看到自己在项目中使用了这一点。仅:将其导入(将其放在您的项目中)并自由地使用它。
(ns world)
(defn save-world
[]
(let [syms (filter identity (distinct (for [i (ns-map *ns*)] (first i))))]
(for [i syms]
(vector i
(ns-resolve *ns* i)))))
(defn destroy-world-but
[saved]
(let [syms (filter identity (distinct (for [i (ns-map *ns*)] (first i))))]
(for [i syms]
(if-not (or (= (ns-resolve *ns* i) (ns-resolve *ns* saved))
(= (ns-resolve *ns* i) (ns-resolve *ns* 'restore-world))
(= (ns-resolve *ns* i) (ns-resolve *ns* '*ns*)))
(ns-unmap *ns* i)))))
(defn restore-world
[saved]
(clojure.core/map
#(intern *ns* (clojure.core/first %) (clojure.core/second %))
saved))
第一的, ,保存世界的状态(您想回到的状态)这样:
(def *save* (save-world))
然后 做任何您想做的事 - 体验。当您准备回到以前的状态时:
(destroy-world-but '*save*)
(restore-world *save*)
而且你应该很好!
(希望这能起作用! LL修订。)
其他提示
这不会总是起作用。您可以从命名空间中删除vars ns-unmap
, ,但是其他代码仍然可能会引用这些定义。
Clojure因为它基于JVM,因此没有像某些常见的LISP或方案实现的“内存图像”概念。
DMTCP可能会以笨拙的方式完成这项工作。 Google在DMTCP上:分布式多线程检查点。我将其用于检查点交互式OCAML程序。
不隶属于 StackOverflow