Macros Clojure宏到";插入“;文件中的代码
我有一个包含一些表格的文件,例如Macros Clojure宏到";插入“;文件中的代码,macros,clojure,Macros,Clojure,我有一个包含一些表格的文件,例如 (clojure.core/defn x [] (clojure.core/+ 5 7)) (clojure.core/defn y [a] (clojure.core/+ a 5)) 我希望在运行前被“插入”到Clojure代码的另一个文件中 大概,我可以使用宏来实现这一点。我尝试编写一个宏来读取文件并对字符串调用load string,但这会导致表单在宏中直接求值 i、 鉴于上述文件,我想 (some-other-code) ... (my-macro)
(clojure.core/defn x [] (clojure.core/+ 5 7))
(clojure.core/defn y [a] (clojure.core/+ a 5))
我希望在运行前被“插入”到Clojure代码的另一个文件中
大概,我可以使用宏来实现这一点。我尝试编写一个宏来读取文件并对字符串调用load string
,但这会导致表单在宏中直接求值
i、 鉴于上述文件,我想
(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)
为什么不在要引入这些函数的地方使用一个简单的名称空间呢
不管怎么说,下面是我认为能起作用的代码:
(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)))
您可以使用内置的
load
功能来实现这一点:
;; assuming foo.clj is on the classpath
(load "foo")
Clojure本身就是这样将Clojure.core
拆分成几个文件的,请参见1.5.1版本的源代码中紧跟其后的几行。还要注意以这种方式加载的文件顶部的(在ns'clojure.core中)
当然,使用宏更灵活,因为它允许您在任意位置插入代码、以任意方式转换代码等。但是,如果您只想在多个文件之间划分名称空间,则加载会更简单