代码之家  ›  专栏  ›  技术社区  ›  Sonicsmooth

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

  •  2
  • Sonicsmooth  · 技术社区  · 14 年前

    我正在尝试从另一个.clj文件中加载和/或编译一个.crj文件。 我这样做是因为我试图加载的文件只包含一堆映射,我打算最终用xml文件替换这些映射。我可以 :use 文件,它会起作用,但我正在尝试加载一组外部数据。

    通过围绕repl的一些随机黑客攻击(通过emacs等),我能够 (load "default_libs") 以及 (compile...) 它以某种方式(使用名称空间限定符的不同组合, ' 和 " )并获得对映射的访问,但在重新启动repl后,它就不再工作了,无论如何,我不得不使用完整的命名空间名称来获取数据。

    这是lib_manager.clj:

    (ns mycad.lib-manager
      (:use [clojure repl]
            [mycad utils]))
    
    (compile 'mycad.default-libs)
    (println mycad.default-libs/default-symbols) 
    

    这是我试图加载的文件, default_libs.clj .这里的数据最终会是一些xml文件,但我在这方面还是很新的,所以现在我只直接写了一堆clojure映射。

    (ns mycad.default-libs)
    (def default-symbols {.... })
    

    所以问题是如何从 .clj 文件,而不使用 (ns...) 而是将其视为数据源,使用 load 或 compile ?

    谢谢你的帮助

    2 回复  |  直到 14 年前
        1
  •  2
  •   kotarak    14 年前

    更改 compile 在你的例子中 load 正如你之前在问题中所描述的那样。然后这个例子就会起作用。

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

    如果只定义了一个映射,则可以使用 load-file 。

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

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

    (def default-symbols (load-string (slurp (io/reader stream))))
    
        2
  •  0
  •   Community Mohan Dere    9 年前

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

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

    因此,您可以加载文件,例如使用函数 read-all 从…起 here ,然后 (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 仅从一开始,它们将在您当前的命名空间中,然后您可以将它们用作简单变量。不过,如果 文件.clj 包含一些名称空间更改表单( (ns..) , (in-ns ..) ),那么事情可能会变得复杂,因为当前的命名空间会发生变化。如果这样的声明是强制性的,并且不能在文件本身中删除,您可以尝试过滤它们, (评估 只有当一个形式是一个定义时,才使用它。

    使现代化 :嗯,我发现了 (评估 + (read-all 在某种意义上相当于 (load-file 以下为:

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

    但在 load-file 即使有更改名称空间的命令,名称空间也不会更改——这些名称空间只是加载到内存中,您可以像往常一样引用其中的符号。看来这正是你所需要的。

    推荐文章