无法加载和编译外部clojure文件

时间:2012-07-25 08:37:49

标签: clojure compilation load libraries

我正在尝试从另一个.clj文件中加载和/或编译.clj文件。 我这样做是因为我正在尝试加载的文件只包含一堆地图,我打算最终用xml文件替换它们。我只能:use该文件并且它可以正常工作,但我正在尝试加载一堆外部数据。

通过对repl的一些随机黑客攻击(通过emacs等),我能够以某种方式(load "default_libs")以及(compile...)(使用命名空间限定符的不同组合,'和{ {1}})并且可以访问地图,但是在重新启动repl之后它再也无法工作了,无论如何我必须使用完整的命名空间名称来获取数据。

这是lib_manager.clj:

"

这是我正在尝试加载的文件(ns mycad.lib-manager (:use [clojure repl] [mycad utils])) (compile 'mycad.default-libs) (println mycad.default-libs/default-symbols) 。这里的数据最终会是一些xml文件,但我现在还很新,所以现在我直接写了一堆clojure地图。

default_libs.clj

所以问题是如何从(ns mycad.default-libs) (def default-symbols {.... }) 文件加载一堆数据而不用.clj将其真正加载到命名空间中,而是使用{{1}将其视为数据源}或(ns...)

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

如您在问题中前面所述,将示例中的compile更改为load。然后这个例子就可以了。

compile用于命名空间的AOT编译。所以这不是你需要的。

如果只定义了一个地图,您可以使用load-file

(def default-symbols (load-file "/file/path.clj"))

如果“文件”实际上位于类路径或某些其他非本地流的某个位置,则会有load-string

(def default-symbols (load-string (slurp (io/reader stream))))

答案 1 :(得分:0)

Lisps是非常动态的语言。作为Lisp的Clojure允许您执行以下操作:

user=> (eval (read-string "(def a 10)"))
#'user/a
user=> a
10

因此您可以加载您的文件,例如使用here中的函数read-all,然后使用(eval所有形式:

(use 'clojure.java.io) ; for (reader ..) function
(import 'java.io.PushbackReader)
....
(doseq [f (read-all (PushbackReader. (reader "your/file.clj")))] (eval f))

然后,如果您的file.clj仅包含(def个帖子,则它们将位于您当前的命名空间中,然后您可以将它们用作简单变量。但是,如果您的file.clj包含一些名称空间更改表单((ns..)(in-ns ..)),那么事情可能会很复杂,因为当前的名称空间会发生变化。如果此类声明是强制性的,并且无法在文件本身中删除,则可以尝试对其进行过滤,(eval只有在定义时才会使用表单。

更新:嗯,我发现(eval + (read-all在某种意义上与(load-file相同:

(load-file "your/file.clj")

但是在load-file的情况下,即使存在命名空间更改命令,命名空间也不会更改 - 这些命名空间只是加载到内存中,您可以照常引用它们中的符号。看来这就是你需要的。