[英]Clojure namespace management - Is there a way to save and restore the state of clojure repl namespaces, imports etc.?
Clojure有大量的函數/宏來處理命名空間和java包導入。 對於我的(有限的)理解,命名空間的設置可以被認為是在clojure過程中的狀態(repl)。
當在REPL會話中迭代地工作時,特別是當(重新)加載源文件時,我發現很容易混淆 - 通常當我在命名空間配置中出錯或語法錯誤時。 其他時候我想嘗試重構命名空間/別名/引用過濾器,但不能在不重新啟動REPL的情況下輕松退出現有的命名空間狀態。
例如,我希望能夠檢查點命名空間配置 - 例如在repl上加載代碼主體之后 - 然后在嘗試在REPL導入的某些庫之后返回到“clean-slate”,這樣我就可以立即測試一個源文件,該文件作為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*)
你應該好好去!
(希望這有效!為我工作 - 如果有問題,請告訴我。我確信有更好的方法可以做到這一點,但這是有效的,這是我今晚有多遠。我確定我'我會修改。)
這並不總是有效。 您可以使用ns-unmap
從命名空間中刪除Vars,但其他代碼段仍可能包含對這些定義的引用。
Clojure,因為它基於JVM,沒有像一些Common Lisp或Scheme實現那樣的“內存映像”概念。
DMTCP可能會以笨拙的方式完成工作。 谷歌在DMTCP:分布式多線程CheckPointing。 我用它來檢查交互式OCaml程序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.