2011-06-22 30 views
5

我試圖使用Clojure doc函數獲取文檔,但無法從REPL中識別它(我正在使用Emacs和SLIME)。下面的步驟描述(每行後錯誤信息如下立即)這是怎麼回事:爲什麼REPL將clojure.core/doc視爲var?

gaidica.core> (doc first) 
; Evaluation aborted. 

Unable to resolve symbol: doc in this context 
    [Thrown class java.lang.Exception] 

gaidica.core> (clojure.core/doc first) 
; Evaluation aborted. 

No such var: clojure.core/doc 
    [Thrown class java.lang.Exception] 

user> (clojure.core/doc first) 
; Evaluation aborted. 

No such var: clojure.core/doc 
    [Thrown class java.lang.Exception] 

user> (doc first) 
------------------------- 
clojure.core/first 
([coll]) 
    Returns the first item in the collection. Calls seq on its 
    argument. If coll is nil, returns nil. 
nil 
user> 

如何我指的是doc功能,並把它視爲一個功能,而不是一個變量?


附錄,11年6月22日,9小時後問題發表

@kotarak做出了最相關的註釋:「請注意,這clojure.core/DOC是1.2和更早clojure.repl/doc是1.3及更高版本。「果然,下面的工作:

user> (clojure.repl/doc first) 
------------------------- 
clojure.core/first 
([coll]) 
    Returns the first item in the collection. Calls seq on its 
    argument. If coll is nil, returns nil. 
nil 
user> 

我能確認的Clojure 1.3活躍:

user> *clojure-version* 
{:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"} 
user> 

然而,這也令人困惑 - 我Leiningen project.clj已指定的Clojure 1.2!

以我自己的經驗,我曾經注意到,即使在更改相關目錄的內容後,基於SLIME的REPL「掛在」Java類路徑值上。解決方案然後是退出Emacs和lein swank,然後重新輸入並重試。我想同樣的,得到了​​以下結果:

user> *clojure-version* 
{:major 1, :minor 2, :incremental 0, :qualifier ""} 
user> 

的唯一結論,我可以做的是,我以前曾REPL使用Clojure的1.3去過。我在之前編寫的項目有使用了Clojure 1.3快照,所以我猜測REPL已經以某種方式「掛在」Clojure 1.3上。

問題解決了,學到了什麼教訓等等。對於獎勵積分,任何人都可以解釋發生什麼事情的原因(使用Clojure 1.2與1.3)?

感謝所有人的貢獻。

+0

我注意到你還沒有接受任何回答您的任何問題。如果你認爲他們足夠,你應該肯定接受一些答案。這是stackoverflow網站的工作原理。 – bmillare

+0

@kotarak和@bmillare:請閱讀我的問題和兩個答案。我認爲你會同意,雖然這兩個答案都試圖有幫助,但都不回答我的問題。這就是爲什麼我還沒有接受。 –

+0

@ gregg-williams對於您的所有其他問題而言,這確實如此,您沒有提供任何反饋意見,無論提出的解決方案是否有幫助。 – kotarak

回答

12

幾個更正。首先,doc是一個宏而不是一個函數。函數和宏也可以存儲在var中。其次,在clojure 1.3中,這可能是您正在使用的版本,doc存儲在var clojure.repl/doc中,而不是clojure.core/doc(如1.2中所示)。在命名空間用戶中,doc是「used」,又名是隱含的「(使用[clojure.repl:只有[doc])」)。當你得到一個新的命名空間,或者甚至用ns創建一個命名空間時,clojure.repl/doc不會自動添加,與'user'不同。

更明確的有關問題:

爲什麼REPL治療clojure.core/DOC作爲一個變種?

clojure中的函數,宏和值都存儲在變量中,或者綁定到一個符號,比如在一個函數或函數中。 clojure.core/doc是持有執行doc的宏的變量。

如何引用doc函數並將它識別爲函數而不是變量?

和所有的lisps一樣,要做一個調用,無論是一個函數還是一個宏,你都必須把函數/宏放在列表的第一個位置。

(<fn/macro> *args) 

所以叫上自己的宏的文檔,你會怎麼做:

(doc doc) 
+3

請注意,'clojure.core/doc'是1.2及更早版本。 'clojure.repl/doc'是1.3及更高版本。 – kotarak

1

的文檔的文檔顯示了它的一個宏,以便與macroexpand顯示了 期待一個變種的名稱擴展它包含一項功能。所以對你的問題的簡短回答是「名字空間中的函數包含在變量中」。

在這樣macroexpand-1的情況下可以是一個良好的開端:

(macroexpand-1 '(doc doc)) 
(clojure.core/print-doc (var doc)) 
sso-config.core> (doc doc) 
------------------------- 
clojure.core/doc 
([name]) 
Macro 
    Prints documentation for a var or special form given its name