2

我有一个包含一些表格的文件,例如

(clojure.core/defn x [] (clojure.core/+ 5 7))
(clojure.core/defn y [a] (clojure.core/+ a 5))

我想在运行前被“插入”到另一个 Clojure 代码文件中。

据推测,我可以使用宏来做到这一点。我尝试编写一个宏来读取文件并调用load-string字符串,但这会导致在宏中直接评估表单。

即给定上面的文件,我想要

(some-other-code) ...

(my-macro)

(some-more-other-code)

扩大到

(some-other-code) ...

(clojure.core/defn x [] (clojure.core/+ 5 7))
(clojure.core/defn y [a] (clojure.core/+ a 5))

(some-more-other-code)
4

2 回答 2

4

您可以使用内置load函数来做到这一点:

;; assuming foo.clj is on the classpath
(load "foo")

Clojure 本身这样做是为了将其拆分为几个文件,请参阅1.5.1 版本的源代码中clojure.core紧随其后的行还要注意(in-ns 'clojure.core)以这种方式加载的文件顶部的 。

当然,使用宏更灵活,因为它允许您在任意位置注入代码,以任意方式对其进行转换等。但是,如果您只想在多个文件之间划分名称空间,load则会更简单。

于 2013-10-19T14:45:17.750 回答
3

为什么不在您想要引入这些功能的地方使用简单的(使用“命名空间”)?

无论如何,这是我认为可以解决问题的代码:

(defn stream []
  (java.io.PushbackReader. (clojure.java.io/reader (clojure.java.io/file "foo.clj"))))

(defmacro insert []
  (let [content (with-open [s (stream)]
                  (loop [forms-so-far []]
                    (if-let [next-form (read s false nil)]
                      (recur (conj forms-so-far next-form))
                      forms-so-far)))]
    `(do ~@content)))
于 2013-10-19T12:48:53.883 回答