我试图做一些我认为很简单的事情,但事实证明并非如此,我认为解决方案可能让我对clojure有了更深入的了解,所以我想我会在这里问。
我希望能够从clojure REPL运行以下内容:
(map #(doc %) v)
其中v
是......某事的向量,我不确定是什么。目标是为某些函数序列打印出doc字符串,但我不确定如何表达该向量。我尝试了几件事:(我会随机选择一些功能)
[+ - first set]
['+ '- 'first 'set]
[`+ `- `first `set]
[(var +) (var -) (var first) (var set)]
[`~+ `~- `~first `~set]
没有工作。我还尝试apply
doc
函数,但这不起作用,因为doc
是一个宏,因此不能成为apply
的参数。我错过了什么?
答案 0 :(得分:3)
(doseq [f ['+ '- 'first 'set]] (eval (list 'doc f)))
答案 1 :(得分: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))
答案 2 :(得分:1)
(defn my-doc [v] (-> v meta :doc))
此函数获取var的元数据,然后从元数据中获取doc字符串。 您可以将其映射到一系列变量:
(map my-doc [(var +) (var -) (var first) (var set)]) ;=> LazySeq of doc-strings
或更短:
(map my-doc [#'+ #'- #'first #'set]) ;=> LazySeq of doc-strings
这不适用于特殊表单,因为它们不会被vars引用。