Where is the "?" being served from?

help-database

#1

When we type “?”, where is the help being served from? Is there a big file somewhere with this information?
I’ve tried searching the .julia folder (for instance length(collection)), but curiously there are no hits.


#2

Okay, if ASCII search cannot find it, then it is probably baked into the compiled files, isn’t it?


#3

Depends what you mean with “served”. Docstrings are attached to objects with

"""
string
"""
object

and the docstring for length is defined at https://github.com/JuliaLang/julia/blob/636f5ad21ff3fa2ff55bbd2f602355d3932c2d5b/base/abstractarray.jl#L124-L143.

These get parsed into Markdown and stored.

If you want to follow the thread you can do

julia> @macroexpand @doc +
:((Base.Docs.doc)((Base.Docs.Binding)(Main, :+)))

julia> @which (Base.Docs.doc)((Base.Docs.Binding)(Main, :+))
doc(binding::Base.Docs.Binding) in REPL at stdlib/v1.0/REPL/src/docview.jl:85

But where they are ultimately stored is in the sysimage (with everything else).


#4

Just to go one level deeper, it’s stored in a hidden dictionary within each module that has docstrings:

julia> getfield(Base, Docs.META)
IdDict{Any,Any} with 729 entries:
  Base.parentmodule               => MultiDoc(Type[Tuple{Module}, Tuple{DataType}, Tuple{Function}, Tuple{Any,Any}], IdDict{Any,Any}(Tuple{Any,Any}=>DocStr(svec("    parentmodule(f::Function, types) ->…
  Base.strip                      => MultiDoc(Type[Tuple{AbstractString}], IdDict{Any,Any}(Tuple{AbstractString}=>DocStr(svec("    strip(str::AbstractString, [chars])\n\nRemove leading and trailing cha…
  Base.__precompile__             => MultiDoc(Type[Union{Tuple{}, Tuple{Bool}}], IdDict{Any,Any}(Union{Tuple{}, Tuple{Bool}}=>DocStr(svec("    __precompile__(isprecompilable::Bool)\n\nSpecify whether t…
  Base.bswap                      => MultiDoc(Type[Tuple{Union{Int8, UInt8}}], IdDict{Any,Any}(Tuple{Union{Int8, UInt8}}=>DocStr(svec("    bswap(n)\n\nReverse the byte order of `n`.\n\n# Examples\n```j…
  Base.any!                       => MultiDoc(Type[Tuple{Any,Any}], IdDict{Any,Any}(Tuple{Any,Any}=>DocStr(svec("    any!(r, A)\n\nTest whether any values in `A` along the singleton dimensions of `r` a…
  ⋮                               => ⋮

julia> getfield(Base, Docs.META)[Docs.Binding(Base, :length)]
Base.Docs.MultiDoc(Type[Union{}, Tuple{AbstractArray}, Tuple{AbstractString}], IdDict{Any,Any}(Union{}=>DocStr(svec("    length(collection) -> Integer\n\nReturn the number of elements in the collection.\n\nUse [`lastindex`](@ref) to get the last valid index of an indexable collection.\n\n# Examples\n```jldoctest\njulia> length(1:5)\n5\n\njulia> length([1, 2, 3, 4])\n4\n\njulia> length([1 2; 3 4])\n4\n```\n"), ```
length(collection) -> Integer

#5

Thanks!


#7

Just checked this out for a (likely unique) name in the Statistics.quantile help using ripgrep (rg), a tool which I only know since very short time. Incredibly fast!

$ rg -al Hyndman /Applications/Julia-1.0.app/
/Applications/Julia-1.0.app/Contents/Resources/julia/share/julia/base.cache
/Applications/Julia-1.0.app/Contents/Resources/julia/lib/julia/sys.dylib
/Applications/Julia-1.0.app/Contents/Resources/julia/share/doc/julia/html/en/search_index.js
/Applications/Julia-1.0.app/Contents/Resources/julia/share/doc/julia/html/en/stdlib/Statistics.html
/Applications/Julia-1.0.app/Contents/Resources/julia/share/julia/stdlib/v1.0/Statistics/src/Statistics.jl