Clojure名称空间管理 - 是否有办法保存和恢复Clojure Repl名称空间,导入等的状态?

StackOverflow https://stackoverflow.com/questions/3480377

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程序。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top