且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Clojure命名空间管理 - 有没有方法来保存和恢复clojure的命名空间,导入等状态?

更新时间:2023-02-20 11:26:52

我确定这里有错误,因为我刚才在回答这个问题时写道,但我看到了自己在我的项目中使用这个,肯定。

 (ns世界)


(defn save-world
[]
(let [syms(filter identity(distinct [for [i(ns-map * ns *)] ))))]
(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)))]
对于[i syms]
(if-not(或(=(ns-resolve * ns * i) )
(ns-resolve * ns *'* ns *))
(ns-resolve * ns *'* ns * unmap * ns * i)))))

(defn restore-world
[saved]
(clojure.core / map
# (clojure.core / first%)(clojure.core / second%))
saved))

首先,保存您的世界(您想要返回的状态),如下所示:

 (def * save *(save-world))

做任何你想要的 - 实验。当你准备回到你原来的状态:

 (destroy-world-but'* save *)
(restore-world * save *)

>

(希望这个工作!为我工作 - 请让我知道如果有一个问题我确定有一个更好的方法来做到这一点,但这是工作,它的我今晚有多远,我相信我会修改。)


Clojure has a large number functions/macros for working with namespaces and java package imports. To my (limited) understanding the set up of namespaces can be considered state in a clojure process (repl).

When working iteratively at a REPL session, especially when source files are (re)-loaded, I can find it easy to get confused - often when I make a mistake or syntax error in namespace configuration. Other times I want to try out refactoring namespaces/aliases/reference filters but can't easily back out of existing namespace state without restarting the REPL.

For example I would like to be able to checkpoint namespace configuration - such as after the main body of code is loaded at the repl - then get back to that "clean-slate" after trying out some library imported at the REPL so that I can immediately test a source file that imports a filtered subset of methods in that library as part of the ns macro.

Can people recommend ways to save and restore namespace configuration?

I'm sure there's something wrong with this, as I just wrote it in answer to this question, but I see myself using this in my projects, for sure. Just :import it (have it in its own file in your project) and use it liberally.

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

First, save a the state of your world (the one you want to go back to) like this:

(def *save* (save-world))

Then do whatever you want–experiment. When you're ready to go back to your former state:

(destroy-world-but '*save*)
(restore-world *save*)

And you should be good to go!

(Hope this works! Was working for me–please let me know if there's a problem. I'm sure there's a better way to do this, too, but this works and it's how far I got tonight. I'm sure I'll revise.)