Clojure函数从命名空间中的函数获取docstring

Clojure函数从命名空间中的函数获取docstring,clojure,Clojure,我想编写一个函数,返回名称空间中公共函数的名称和docstring,如下所示: (ns familiar.core (:require [clojure.repl :refer [doc]] ...)) ;; various functions with docstrings here (defn help "Halp!" [] (let [fns (keys (ns-publics 'familiar.core))] (for [f fns

我想编写一个函数,返回名称空间中公共函数的名称和docstring,如下所示:

(ns familiar.core
  (:require [clojure.repl :refer [doc]]
            ...))

;; various functions with docstrings here

(defn help 
  "Halp!"
  []
  (let [fns (keys (ns-publics 'familiar.core))]
    (for [f fns]
      [f (with-out-str (doc f))])))
当我在REPL中调用
(帮助)
时,docstring没有以下功能:

familiar.core=> (help)
([save-experiment ""] [load-experiment ""] [add-data ""] [help ""] ... )
但是在REPL中调用
(不带str(doc add data))
正如我所期望的那样:

familiar.core=> (with-out-str (doc add-data))
"-------------------------\nfamiliar.core/add-data\n([& coll])\n
Adds instances of variables with values at active date.\n  Examp
le:\n (add-data \"mice\" 6 \"cats\" 2 \"dogs\" 0)\n"

这是怎么回事?

doc
是一个宏,因此它无法在调用上下文中计算本地
f
。相反,您只需调用
(doc f)
ovr和over

解决这个问题的最简单方法是绕过
doc
宏,直接查看它用来生成文档的数据:vars上的元数据

(defn help 
  "Halp!"
  [x]
  (for [[name var] (ns-publics 'familiar.core)]
    [name (:doc (meta var))]))

一个更糟糕的选择(只是为了说明这一点)是将原始代码中的
(doc f)
替换为
(eval`(doc~f))
。谢谢!我以前也遇到过同样的问题,并按照A.韦伯提到的方法解决了它,但你的方法更理智。