How to get doc string of function programmatically?

I’m trying to make a function that will get the doc string of a given function. I am confused why there is an issue in the code below:

using Markdown: plain

function get_doc_string(
    f::Function
)::String
    return plain(@doc f)
end

"""
Maximum infection density: maximum([u_t[2] for u_t in u])
"""
function qoi_max_I(u, t)
    return maximum([u_t[2] for u_t in u])
end



z = qoi_max_I

println("Literal doc call and literal function name   : $(plain(@doc qoi_max_I))")
println("Literal doc call and variable-stored function: $(plain(@doc z))")
println("get_doc_string and literal function name     : $(get_doc_string(qoi_max_I))")
println("get_doc_string and variable-stored function  : $(get_doc_string(z))")

My output is this:

Literal doc call and literal function name   : Maximum infection density: maximum([u*t[2] for u*t in u])

Literal doc call and variable-stored function: Maximum infection density: maximum([u*t[2] for u*t in u])

get_doc_string and literal function name     : No documentation found.

Binding `f` does not exist.

get_doc_string and variable-stored function  : No documentation found.

Binding `f` does not exist.

How can I avoid this issue, or must I use @doc directly each time I need to collect doc strings?

You can look at @macroexpand doc foo to see what it does. Under the hood, it needs a module and a symbol, e.g.:

get_doc_string(mod::Module, f::Function) = Docs.doc(Docs.Binding(mod, Symbol(f)))

See also Public API for `Docs.doc` · Issue #52747 · JuliaLang/julia · GitHub

4 Likes

Thanks very much! You meant @macroexpand @doc foo, yes? Is it discouraged to do something like this since Docs.Binding is private? I see that you commented on the github issue, perhaps this will be changed in the future