[英]How can I apply clojure's doc function to a sequence of functions
I was trying to do something I thought would be simple but has turned out to be not so and I think the solution might give me a deeper understanding of clojure so I figured I'd ask here. 我试图做一些我认为简单的事情,但事实并非如此,我认为该解决方案可能使我对clojure有更深入的了解,所以我想在这里问一下。
I want to be able to run the following from a clojure REPL: 我希望能够从clojure REPL运行以下命令:
(map #(doc %) v)
where v
is a vector of...something, I'm not sure what. 其中
v
是...某物的向量,我不确定是什么。 The goal was to print out the doc strings for some sequence of functions, but I'm not sure how to express that vector. 目的是打印出某些功能序列的文档字符串,但是我不确定如何表达该向量。 I've tried a couple of things: (I'll pick a few functions out at random)
我尝试了几件事:(我会随机选择一些功能)
[+ - first set]
['+ '- 'first 'set]
[`+ `- `first `set]
[(var +) (var -) (var first) (var set)]
[`~+ `~- `~first `~set]
None work. 没有工作。 I also tried to
apply
the doc
function but that doesn't work since doc
is a macro and as such cannot be an argument to apply
. 我也尝试
apply
doc
函数,但是由于doc
是一个宏,因此不能作为apply
的参数,因此无法正常工作。 What am I missing? 我想念什么?
(doseq [f ['+ '- 'first 'set]] (eval (list 'doc f)))
In Clojure 1.2 you can use the function print-doc
: 在Clojure 1.2中,您可以使用函数
print-doc
:
(print-doc #'fisrt)
like this 像这样
(map print-doc [#'fisrt #'+])
#'fisrt
is the same as (var first)
. #'fisrt
与(var first)
相同。
Note that this will not work for special forms: (doc def)
works, but (print-doc #
def)` gives: 请注意,这不适用于特殊形式:
(doc def)
有效,但是(print-doc #
def)`给出:
java.lang.Exception: Unable to resolve var: def in this context (NO_SOURCE_FILE:7)
This is because special forms aren't defined in vars. 这是因为在vars中没有定义特殊形式。 You can see how doc works for them by using
macroexpand-1
: 您可以使用
macroexpand-1
查看doc如何为它们工作:
user=> (macroexpand-1 '(doc def))
(clojure.core/print-special-doc (quote def) "Special Form" (clojure.core/special-form-anchor (quote def)))
In Clojure 1.3 print-doc
is moved in the clojure.repl
namespace and is private, so you cannot execute it directly. 在Clojure 1.3中,
print-doc
在clojure.repl
命名空间中移动并且是私有的,因此您不能直接执行它。 You can enter the ns: 您可以输入ns:
user=> (in-ns 'clojure.repl)
clojure.repl=> (print-doc (meta #'first))
clojure.repl=> (map #(print-doc (meta %)) [#'first #'+])
As you can see, Clojure 1.3 requires getting the metadata explicitly. 如您所见,Clojure 1.3需要显式获取元数据。
If you need to execute this from a different namespace you'll have to export the function. 如果需要从其他名称空间执行此操作,则必须导出函数。 One way to do so is to define a new function:
一种方法是定义一个新函数:
clojure.repl=> (defn my-print-doc [m] (print-doc m))
user=> (clojure.repl/my-print-doc (meta #'first))
(defn my-doc [v] (-> v meta :doc))
This function takes the meta data of a var and then gets the doc string out of the meta data. 此函数获取var的元数据,然后从元数据中获取doc字符串。 You can map it over a sequence of vars:
您可以将其映射到一系列变量上:
(map my-doc [(var +) (var -) (var first) (var set)]) ;=> LazySeq of doc-strings
or shorter: 或更短:
(map my-doc [#'+ #'- #'first #'set]) ;=> LazySeq of doc-strings
This doesn't work for special forms, since they are not referenced by vars. 这不适用于特殊形式,因为它们没有被vars引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.