2011-12-01 71 views
2

我試圖做一些我認爲很簡單的事情,但事實證明並非如此,我認爲解決方案可能會讓我更深入地理解clojure,所以我想我會在這裏問。如何將clojure的doc函數應用於一系列函數

我希望能夠運行從Clojure的REPL如下:

(map #(doc %) v) 

其中v是的...一些載體,我不知道是什麼。目標是打印一些函數序列的文檔字符串,但我不知道如何表示該向量。我試了幾件事:(我會隨機挑選幾個函數)

[+ - first set] 
['+ '- 'first 'set] 
[`+ `- `first `set] 
[(var +) (var -) (var first) (var set)] 
[`~+ `~- `~first `~set] 

沒有工作。我也嘗試applydoc函數,但這是行不通的,因爲doc是一個宏,因此不能作爲apply的參數。我錯過了什麼?

回答

3
(doseq [f ['+ '- 'first 'set]] (eval (list 'doc f))) 
+1

我想這雖然,以適應我的問題我想修改它以'(圖#(EVAL(名單「的文檔(符號%)))+ - 第一組])' – stand

+0

我覺得更好如果你離開你的想法。 – BLUEPIXY

+0

(def v'[+ - first set])(map#(eval(list'doc%))v); return nil – BLUEPIXY

1

在Clojure中1.2,你可以使用函數print-doc

(print-doC#'fisrt) 

這樣

(map print-doc [#'fisrt #'+]) 

#'fisrt相同(var first)

注意,這不適用於特殊形式的工作:(doc def)作品,但(print-doC# DEF)`給:

java.lang.Exception: Unable to resolve var: def in this context (NO_SOURCE_FILE:7) 

這是因爲特殊的形式沒有在瓦爾定義。你可以看到文檔如何使用macroexpand-1爲他們工作:

user=> (macroexpand-1 '(doc def)) 
(clojure.core/print-special-doc (quote def) "Special Form" (clojure.core/special-form-anchor (quote def))) 

在Clojure中1.3 print-doc移動在clojure.repl命名空間是私有的,所以你不能直接執行它。您可以輸入ns:

user=> (in-ns 'clojure.repl) 
clojure.repl=> (print-doc (meta #'first)) 
clojure.repl=> (map #(print-doc (meta %)) [#'first #'+]) 

正如您所見,Clojure 1.3需要明確獲取元數據。

如果您需要從不同的名稱空間執行此操作,則必須導出該函數。這樣做的一個方法是定義一個新的功能:

clojure.repl=> (defn my-print-doc [m] (print-doc m)) 
user=> (clojure.repl/my-print-doc (meta #'first)) 
1
(defn my-doc [v] (-> v meta :doc)) 

此功能需要一個變種的元數據,然後獲取文檔串出的元數據。 您可以通過它映射瓦爾的序列:

(map my-doc [(var +) (var -) (var first) (var set)]) ;=> LazySeq of doc-strings 

或更短:

(map my-doc [#'+ #'- #'first #'set]) ;=> LazySeq of doc-strings 

這並不適用於特殊形式的工作,因爲他們沒有被引用瓦爾。