Clojure namespace management - Is there a way to save and restore the state of clojure repl namespaces, imports etc.?

后端 未结 3 1172
独厮守ぢ
独厮守ぢ 2021-02-04 10:38

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

相关标签:
3条回答
  • 2021-02-04 11:01

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

    0 讨论(0)
  • 2021-02-04 11:09

    This won't always work. You can remove Vars from a namespace with ns-unmap, but other pieces of code may still hold references to those definitions.

    Clojure, because it is based on the JVM, has no concept of a "memory image" like some Common Lisp or Scheme implementations.

    0 讨论(0)
  • 2021-02-04 11:12

    DMTCP might do the job in a clumsy way. Google on DMTCP: Distributed MultiThreaded CheckPointing. I use it to checkpoint interactive OCaml programs.

    0 讨论(0)
提交回复
热议问题