簡體   English   中英

Clojure名稱空間管理 - 有沒有辦法保存和恢復clojure repl名稱空間,導入等的狀態?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM