James
James

Reputation: 367

Clojure function to get docstrings from functions in a namespace

I want to write a function that returns the names and docstrings of the public functions in my namespace, like so:

(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))])))

When I call (help) in the REPL, the docstrings don't come with the functions:

familiar.core=> (help)
([save-experiment ""] [load-experiment ""] [add-data ""] [help ""] ... )

But calling (with-out-str (doc add-data)) in the REPL works as I'd expect:

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"

What's going on here?

Upvotes: 5

Views: 1468

Answers (1)

amalloy
amalloy

Reputation: 91857

doc is a macro, so it cannot evaluate the local f in the calling context. Instead, you are simply calling (doc f) ovr and over.

The easiest approach to solve this is to go around the doc macro, and look directly at the data that it uses to produce documentation: metadata on vars.

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

Upvotes: 8

Related Questions