我想在clojure中的沙盒命名空间中运行load-file

时间:2014-12-04 18:41:51

标签: clojure namespaces

我是Clojure的新手,为了娱乐/教育,我正在为lein编写通用的迁移框架。该系统必须做的一件事是从磁盘读取一个clojure文件,然后运行up函数或down函数。我认为这个文件应该可以在一个临时命名空间中进行评估,但是我无法让它工作。这就是我到目前为止所拥有的:

(def user-namespace (create-ns 'leiningen.generic-migrate.user-eval))

(defn load-migration-file [file]
  (binding [*ns* user-namespace]
    (load-file (.getAbsolutePath file))
    (keys (ns-publics *ns*))))

这给了我错误:

Unable to resolve symbol: defn in this context

我的问题是,使用加载文件的最佳方法是什么,然后运行已定义的函数,而没有人在我的命名空间中覆盖内容的风险?

1 个答案:

答案 0 :(得分:3)

(defmacro with-ns
  "Evaluates body in another namespace.  ns is either a namespace
  object or a symbol.  This makes it possible to define functions in
  namespaces other than the current one."
  [ns & body]
  `(binding [*ns* (the-ns ~ns)]
     ~@(map (fn [form] `(eval '~form)) body)))

(defmacro with-temp-ns
  "Evaluates body in an anonymous namespace, which is then immediately
  removed.  The temporary namespace will 'refer' clojure.core."
  [& body]
  `(try
     (create-ns 'sym#)
     (let [result# (with-ns 'sym#
                     (clojure.core/refer-clojure)
                     ~@body)]
       result#)
     (finally (remove-ns 'sym#))))