2012-07-25 50 views
2

我想從另一個.clj文件中加載和/或編譯.clj文件。 我這樣做是因爲我想加載的文件只包含一堆地圖,我打算最終用xml文件替換這些文件。我可以只是:use該文件,它會工作,但我試圖通過加載外部一堆數據的練習。無法加載和編譯外部clojure文件

通過圍繞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...)命名空間,而是把它當作使用或者loadcompile數據的來源?

感謝所有幫助

回答

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)))) 
0

Lisps是非常動態的語言。作爲Lisp的Clojure允許您執行以下操作:

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

因此,您可以加載文件,例如具有功能read-allhere,然後(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 initions,他們會在你當前的命名空間,那麼你可以用它們作爲簡單的變量。但是,如果您的file.clj包含一些命名空間更改表單((ns..),(in-ns ..)),則事情可能會變得複雜,因爲當前命名空間將會更改。如果這樣的聲明是強制性的並且不能在文件本身中被刪除,那麼您可以嘗試對它們進行過濾,只有當它是一個定義時。

更新:HM,我發現(eval + (read-all在某種意義上等同於(load-file

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

但在load-file的情況下,即使有命名空間不會改變命名空間變化命令 - 這些命名空間只是加載到內存中,您可以照常參考它們中的符號。看來,這是你需要的。