Clojureネームスペース管理 - Clojure Replネームスペース、インポートなどの状態を保存および復元する方法はありますか?
-
28-09-2019 - |
質問
Clojureには、名前空間とJavaパッケージのインポートを操作するための多数の機能/マクロがあります。私の(限られた)名前空間のセットアップは、Clojureプロセス(REPL)で状態と見なすことができます。
特にソースファイルが(RE)ロードされている場合、REPLセッションで繰り返し作業する場合、混乱するのは簡単です - 多くの場合、名前空間構成で間違いや構文エラーを犯したときに。他にも、名前空間/エイリアス/リファレンスフィルターのリファクタリングを試してみたいが、REPLを再起動せずに既存の名前空間状態から簡単にバックアウトできません。
たとえば、CheckPointの名前空間構成をチェックすることができます - REPLでコードの本文がロードされた後など、その後、REPLでインポートされたライブラリを試した後、その「クリーンスレート」に戻り、できるようになります。 NSマクロの一部として、そのライブラリにメソッドのフィルターされたサブセットをインポートするソースファイルをすぐにテストします。
名前空間構成を保存および復元する方法を推奨できますか?
解決
あると確信しています なにか これは間違っていますが、この質問に答えて書いたばかりですが、確かにプロジェクトでこれを使用していると思います。 Just:インポートし(プロジェクトで独自のファイルに入れてください)、自由に使用します。
(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改訂。)
他のヒント
これは常に機能するとは限りません。名前空間からVARを削除できます ns-unmap
, 、しかし、他のコードはそれらの定義への参照を保持する場合があります。
Clojureは、JVMに基づいているため、一般的なLISPやスキームの実装などの「メモリイメージ」の概念はありません。
DMTCPは不器用な方法で仕事をするかもしれません。 Google on DMTCP:分散マルチスレッドチェックポイント。 Interactive OCAMLプログラムをチェックポイントに使用します。