12

Clojure には、名前空間と Java パッケージのインポートを操作するための多数の関数/マクロがあります。私の(限られた)理解では、名前空間の設定は clojure プロセス (repl) の状態と見なすことができます。

REPL セッションで反復的に作業する場合、特にソース ファイルが (再) ロードされる場合、混乱しやすいことがわかります。多くの場合、名前空間の構成で間違いや構文エラーを犯したときに発生します。また、名前空間/エイリアス/参照フィルターのリファクタリングを試してみたい場合もありますが、REPL を再起動しないと既存の名前空間の状態を簡単に元に戻すことができません。

たとえば、コードの本体がreplにロードされた後など、名前空間の構成をチェックポイントできるようにしたいと思います。次に、REPLでインポートされたライブラリを試した後、その「クリーンスレート」に戻ります。 ns マクロの一部として、そのライブラリ内のフィルター処理されたメソッドのサブセットをインポートするソース ファイルをすぐにテストします。

名前空間の構成を保存および復元する方法を推奨できますか?

4

3 に答える 3

10

この質問に答えて書いたばかりなので、これには何か問題があると確信していますが、プロジェクトでこれを使用していることは確かです。:import (プロジェクト内の独自のファイルに含める) だけで、自由に使用できます。

(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*)

そして、あなたは行く準備ができているはずです!

(これでうまくいくといいのですが!うまくいきました。問題があれば教えてください。これを行うためのより良い方法もあると思いますが、これはうまくいき、今夜どれだけ遠くまで到達したか.私は確信しています.見直します。)

于 2010-08-14T02:19:46.697 に答える
6

これは常に機能するとは限りません。を使用して名前空間から Vars を削除できますがns-unmap、他のコードはそれらの定義への参照を保持している可能性があります。

Clojure は JVM に基づいているため、Common Lisp や Scheme の実装のような「メモリ イメージ」の概念がありません。

于 2010-08-14T16:10:13.187 に答える
1

DMTCP は不器用な方法で仕事をするかもしれません。DMTCP 上の Google: 分散マルチスレッド CheckPointing。インタラクティブな OCaml プログラムのチェックポイントに使用します。

于 2011-04-03T00:29:05.610 に答える