Управление пространством имен Clojure - Является там способом сохранить и восстановить состояние clojure repl пространства имен, импорт и т.д.?

Clojure имеет большое количество функции/макросы для работы с пространствами имен и импортом пакета Java. К моему (ограниченному) пониманию набора пространств имен может считаться состоянием в процессе clojure (repl).

При работе многократно на сессии REPL, особенно когда исходные файлы (ре) - загружены, мне может быть легко запутаться - часто, когда я делаю ошибку или синтаксическую ошибку в конфигурации пространства имен. Другие времена я хочу испытать фильтры пространств имен/псевдонимов/ссылки рефакторинга, но не могу легко отступить из существующего состояния пространства имен, не перезапуская REPL.

Например, я хотел бы смочь отметить конфигурацию пространства имен контрольной точкой - такой как, после того, как основная часть кода загружается в repl - затем возвращаются к тому "чистому листу" после испытания некоторой библиотеки, импортированной в REPL так, чтобы я мог сразу протестировать исходный файл, который импортирует фильтрованное подмножество методов в той библиотеке как часть макроса нс.

Люди могут рекомендовать способам сохранить и восстановить конфигурацию пространства имен?

11
задан Alex Stoddard 13 August 2010 в 20:16
поделиться

2 ответа

Я уверен, что в этом есть что-то , потому что я только что написал это в ответ на этот вопрос, но я точно вижу, что использую это в своих проектах. Просто: импортируйте его (поместите в отдельный файл в вашем проекте) и используйте его без ограничений.

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

И вам должно быть хорошо!

(Надеюсь, это сработает! У меня сработало - пожалуйста, дайте мне знать, если возникнет проблема. Я уверен, что есть и лучший способ сделать это, но это работает, и это то, как далеко я продвинулся сегодня вечером. Я обязательно исправлю.)

10
ответ дан 3 December 2019 в 07:10
поделиться

Это не всегда работает. Вы можете удалить Vars из пространства имен с помощью ns-unmap , но другие фрагменты кода могут по-прежнему содержать ссылки на эти определения.

Clojure, поскольку он основан на JVM, не имеет концепции «образа памяти», как некоторые реализации Common Lisp или Scheme.

6
ответ дан 3 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: