如何获取clojure函数参数的元数据?

时间:2012-09-14 22:03:47

标签: clojure metadata

有没有办法在clojure中一般性地获取函数参数的元数据?实际上,in this question发布的答案通常

user> (defn foo "informative dox!" [] 1)
#'user/foo
user> (defmacro get-docs [func] `(:doc (meta (var ~func))))
#'user/get-docs
user> (get-docs foo)
"informative dox!"
user> (get-docs (identity foo))
; Evaluation aborted.
user> (defn process-docs [f] (let [docs (get-docs f)] (reverse docs)))
; Evaluation aborted.

倒数第二行不起作用,因为您无法在列表var上调用(identity foo),并且最后一行甚至无法编译,因为编译器抱怨无法解决f

我发现这个问题的大多数解决方案都依赖于你可以访问函数定义中的符号或类似的东西,这样你就可以做(resolve 'f)或{{{{{{ 1}}。但是我想要一些我可以在函数的参数上使用的东西,在那里你不知道这些信息。

基本上,我想要一个表达式,我可以代替下面的问号来获取(var f)的元数据:

#'map

1 个答案:

答案 0 :(得分:5)

尽管可能,它仍然满口:

(let [x map]
   (:doc (meta (second (first (filter #(and (var? (second %))
                                            (= x (var-get (second %))))
                                      (ns-map *ns*)))))))

产生所需的结果:

"Returns a lazy sequence consisting of the result of applying f to the
 set of first items of each coll, followed by applying f to the set
 of second items in each coll, until any one of the colls is\n  exhausted.  Any remaining items in other colls are ignored. Function
 f should accept number-of-colls arguments."

引擎盖名称空间本质上是名称到vars的映射,而vars包含函数。你可以在这些变量的内容中搜索与你正在寻找的函数相匹配的变量,然后查看它的相关var并从该变量中获取元数据。