Документация
Доступ к документации
Документация доступна в REPL или в IJulia, набрав ? за которым следует имя функции или макроса, и нажав Enter. Например,
?cos ?@time ?r""
будет отображена документация для соответствующей функции, макроса или строкового макроса соответственно. Большинство сред Julia предоставляют способ доступа к документации напрямую:
- VS Code отображает документацию при наведении курсора на имя функции. Также вы можете использовать панель Julia в боковой панели для поиска документации.
- В Pluto откройте панель "Live Docs" в правом нижнем углу.
- В Juno используя
Ctrl-J, Ctrl-Dотобразится документация для объекта
под курсором.
Написание документации
Julia позволяет разработчикам и пользователям пакетов легко документировать функции, типы и другие объекты с помощью встроенной системы документации.
Базовый синтаксис прост: любая строка, появляющаяся непосредственно перед объектом (функцией, макросом, типом или экземпляром), будет интерпретироваться как документация к нему (они называются docstrings). Обратите внимание, что между docstring и документируемым объектом не должно быть пустых строк или комментариев. Вот базовый пример:
"Tell whether there are too foo items in the array." foo(xs::Array) = ...
Документация интерпретируется как Markdown, поэтому вы можете использовать отступы и кодовые блоки, чтобы отделить примеры кода от текста. Технически, любой объект может быть связан с любым другим как метаданные; Markdown является по умолчанию, но можно создать другие строковые макросы и передать их в макрос @doc так же.
Поддержка Markdown реализована в стандартной библиотеке Markdown и полный список поддерживаемого синтаксиса см. в документации.
Вот более сложный пример, все еще использующий Markdown:
"""
bar(x[, y])
Compute the Bar index between `x` and `y`.
If `y` is unspecified, compute the Bar index between all pairs of columns of `x`.
# Examples
```julia-repl
julia> bar([1, 2], [1, 2])
1
```
"""
function bar(x, y) ...
Как и в примере выше, мы рекомендуем следовать некоторым простым соглашениям при написании документации:
-
Всегда отображайте сигнатуру функции в верхней части документации, с отступом в четыре пробела, чтобы она печаталась как код Julia.
Она может быть идентична сигнатуре в коде Julia (например,
mean(x::AbstractArray)), или упрощенной форме. Дополнительные аргументы должны быть представлены со своими значениями по умолчанию (т. е.f(x, y=1)), когда это возможно, в соответствии с фактическим синтаксисом Julia. Дополнительные аргументы, которые не имеют значения по умолчанию, должны быть помещены в скобки (т. е.f(x[, y])иf(x[, y[, z]])). Альтернативным решением является использование нескольких строк: одна без дополнительных аргументов, а другие — с ними. Это решение также может использоваться для документирования нескольких связанных методов данной функции. Когда функция принимает много ключевых аргументов, включайте только заполнитель<keyword arguments>в сигнатуре (т. е.f(x; <keyword arguments>)), и предоставьте полный список в разделе# Arguments(см. пункт 4 ниже). -
Включите однострочное описание того, что делает функция или что представляет собой объект, после упрощенного блока сигнатуры. При необходимости, предоставьте больше подробностей во втором абзаце, после пустой строки.
Однострочное предложение должно использовать повелительное наклонение ("Сделайте это", "Возвращает это") вместо третьего лица (не пишите "Возвращает длину...") при документировании функций. Оно должно заканчиваться точкой. Если смысл функции нельзя легко обобщить, разделение его на отдельные составные части может быть полезным (хотя это не должно рассматриваться как абсолютное требование для каждого отдельного случая).
-
Не повторяйтесь.
Поскольку имя функции указано в сигнатуре, нет необходимости начинать документацию с "Функция
bar...": переходите сразу к сути. Аналогично, если подпись указывает типы аргументов, упоминание их в описании избыточно. -
Предоставляйте список аргументов только тогда, когда это действительно необходимо.
Для простых функций часто понятнее указать роль аргументов непосредственно в описании назначения функции. Список аргументов только повторит информацию, которая уже была предоставлена где-то еще. Однако предоставление списка аргументов может быть хорошей идеей для сложных функций с многими аргументами (особенно ключевыми аргументами). В этом случае вставьте его после общего описания функции, в заголовке
# Arguments, с одним-пунктом для каждого аргумента. В списке должны быть указаны типы и значения по умолчанию (если таковые имеются) аргументов:""" ... # Arguments - `n::Integer`: the number of elements to compute. - `dim::Integer=1`: the dimensions along which to perform the computation. ... """
-
Предоставляйте подсказки о связанных функциях.
Иногда существуют функции, связанные по функциональности. Для повышения обнаруживаемости предоставьте короткий список таких функций в абзаце
See also.See also [`bar!`](@ref), [`baz`](@ref), [`baaz`](@ref).
-
Включите примеры кода в разделе
# Examples.Примеры, когда это возможно, должны быть написаны как doctests. doctest — это кодовый блок с ограждением (см. Блоки кода), начинающийся с
```jldoctestи содержит любое количествоjulia>запросов вместе с входами и ожидаемыми выходами, имитирующими Julia REPL.Doctests активируются с помощью
Documenter.jl. Более подробную документацию см. в руководстве Documenter по https://juliadocs.github.io/Documenter.jl/.Например, в следующей docstring определена переменная
a, и после этого отображается ожидаемый результат, как он печатается в Julia REPL:""" Some nice documentation here. # Examples ```jldoctest julia> a = [1 2; 3 4] 2×2 Array{Int64,2}: 1 2 3 4 ``` """Вызовы
randи других функций, связанных с RNG, следует избегать в doctests, так как они не будут давать согласованные результаты в различных сессиях Julia. Если вы хотите продемонстрировать функциональность, связанную с генерацией случайных чисел, одним из вариантов является явное построение и инициализация объекта RNG (см.Random) и передача его в тестируемые функции.Размерность слова операционной системы (
Int32илиInt64), а также различие разделителей путей (/или\) также повлияют на воспроизводимость некоторых doctests.Обратите внимание, что пробелы в вашем doctest важны! Doctest потерпит неудачу, если вы неправильно выровняете вывод при форматировании массива, например.
Вы можете запустить
make -C doc doctest=trueдля запуска всех doctests в руководстве и документации API Julia, что гарантирует корректную работу вашего примера.Чтобы указать, что результат вывода усечен, вы можете написать
[...]в строке, где следует остановить проверку. Это полезно, чтобы скрыть трассировку стека (которая содержит не постоянные ссылки на строки кода Julia), когда doctest показывает, что бросается исключение, например:```jldoctest julia> div(1, 0) ERROR: DivideError: integer division error [...] ```
Примеры, которые нельзя протестировать, должны быть написаны внутри кодовых блоков с ограждением, начинающихся с
```julia, чтобы они правильно выделялись в сгенерированной документации.По возможности примеры должны быть самодостаточными и выполняемыми, чтобы читатели могли их попробовать, не включая никаких зависимостей.
-
Используйте обратные кавычки для идентификации кода и уравнений.
Идентификаторы и фрагменты кода Julia всегда должны отображаться в обратных кавычках
`для выделения. Уравнения в синтаксисе LaTeX можно вставлять между двойными обратными кавычками``. Используйте символы Unicode вместо их последовательностей экранирования LaTeX, т. е.``α = 1``вместо``\\alpha = 1``. -
Поместите начальные и конечные
"""символы на отдельных строках.То есть напишите:
""" ... ... """ f(x, y) = ...
а не:
"""... ...""" f(x, y) = ...
Это делает более понятным, где начинаются и заканчиваются docstrings.
-
Учитывайте ограничение длины строки, используемое в окружающем коде.
Docstrings редактируются с помощью тех же инструментов, что и код. Поэтому должны применяться те же соглашения. Рекомендуется, чтобы длина строк не превышала 92 символа.
Предоставляйте информацию, позволяющую настраиваемым типам реализовывать функцию в разделе
# Implementation. Эти сведения о реализации предназначены для разработчиков, а не для пользователей, объясняя, например, какие функции следует переопределять и какие функции автоматически используют соответствующие отказоустойчивые механизмы. Такие детали лучше всего сохранять отдельно от основного описания поведения функции.Для длинных docstrings рассмотрите возможность разделения документации с заголовком
# Extended help. Типичный режим справки будет отображать только материал, расположенный над заголовком; вы можете получить доступ к полной справке, добавив знак вопроса в начале выражения (т.е. "??foo" вместо "?foo").
Функции и методы
Функции в Julia могут иметь несколько реализаций, называемых методами. Хотя для универсальных функций рекомендуется иметь единственную цель, Julia позволяет документировать методы индивидуально, если это необходимо. В общем случае, только наиболее универсальный метод должен быть документирован, или даже сама функция (т. е. объект, созданный без методов с помощью function bar end). Конкретные методы должны быть документированы только если их поведение отличается от более универсальных. В любом случае, они не должны повторять информацию, предоставленную где-либо еще. Например:
"""
*(x, y, z...)
Multiplication operator. `x * y * z *...` calls this function with multiple
arguments, i.e. `*(x, y, z...)`.
"""
function *(x, y, z...)
# ... [implementation sold separately] ...
end
"""
*(x::AbstractString, y::AbstractString, z::AbstractString...)
When applied to strings, concatenates them.
"""
function *(x::AbstractString, y::AbstractString, z::AbstractString...)
# ... [insert secret sauce here] ...
end
help?> *
search: * .*
*(x, y, z...)
Multiplication operator. x * y * z *... calls this function with multiple
arguments, i.e. *(x,y,z...).
*(x::AbstractString, y::AbstractString, z::AbstractString...)
When applied to strings, concatenates them.
При получении документации для универсальной функции метаданные для каждого метода конкатенируются с функцией catdoc, которая, конечно, может быть переопределена для настраиваемых типов.
Расширенное использование
Макрос @doc связывает свой первый аргумент со вторым в словаре модуля META.
Для облегчения написания документации, парсер обрабатывает имя макроса @doc специальным образом: если вызов @doc имеет один аргумент, но после одиночной строки появляется другое выражение, то это дополнительное выражение добавляется как аргумент к макросу. Таким образом, следующий синтаксис анализируется как вызов макроса @doc с двумя аргументами:
@doc raw""" ... """ f(x) = x
Это позволяет использовать в качестве docstring выражения, отличные от обычных строковых литералов (например, макрос raw"").
При использовании макроса @doc (или, равнозначно, функции doc) для получения документации, будет произведен поиск метаданных, относящихся к заданному объекту, во всех словарях META, и они будут возвращены. Возвращаемый объект (например, некоторый контент Markdown) по умолчанию будет отображаться интеллектуально. Данный дизайн также делает систему документации удобной для программирования, например, для повторного использования документации между различными версиями функции:
@doc "..." foo! @doc (@doc foo!) foo
Или для использования с функциональностью метапрограммирования Julia:
for (f, op) in ((:add, :+), (:subtract, :-), (:multiply, :*), (:divide, :/))
@eval begin
$f(a,b) = $op(a,b)
end
end
@doc "`add(a,b)` adds `a` and `b` together" add
@doc "`subtract(a,b)` subtracts `b` from `a`" subtract
Документация, написанная в не-главных блоках, таких как begin, if, for, и let, добавляется в систему документации по мере оценки блоков. Например:
if condition()
"..."
f(x) = x
end
добавит документацию к f(x), когда condition() будет true. Обратите внимание, что даже если f(x) выйдет за пределы области видимости в конце блока, его документация останется.
Можно использовать метапрограммирование для помощи в создании документации. При использовании интерполяции строк в строке документации необходимо использовать дополнительный $, как показано в $($name).
for func in (:day, :dayofmonth)
name = string(func)
@eval begin
@doc """
$($name)(dt::TimeType) -> Int64
The day of month of a `Date` or `DateTime` as an `Int64`.
""" $func(dt::Dates.TimeType)
end
end
Динамическая документация
Иногда соответствующая документация для экземпляра типа зависит от значений полей этого экземпляра, а не только от самого типа. В этих случаях можно добавить метод к Docs.getdoc для вашего пользовательского типа, который возвращает документацию для каждого экземпляра. Например,
struct MyType
value::Int
end
Docs.getdoc(t::MyType) = "Documentation for MyType with value $(t.value)"
x = MyType(1)
y = MyType(2)
?x отобразит «Документация для MyType со значением 1», в то время как ?y отобразит «Документация для MyType со значением 2».
Руководство по синтаксису
Это руководство предоставляет всесторонний обзор того, как прикрепить документацию ко всем конструкциям синтаксиса Julia, для которых это возможно.
В следующих примерах используется "..." для иллюстрации произвольной строки документации.
$ и \ символы
Символы $ и \ всё ещё обрабатываются как интерполяция строк или начало последовательности экранирования в строках документации. Макрос строки raw"" вместе с макросом @doc может использоваться для избежания необходимости экранирования. Это полезно, когда строки документации включают LaTeX или примеры кода Julia, содержащие интерполяцию:
@doc raw""" ```math \LaTeX ``` """ function f end
Функции и методы
"..." function f end "..." f
Добавляет строку документации "..." к функции f. Первая версия предпочтительнее, но обе эквивалентны.
"..."
f(x) = x
"..."
function f(x)
x
end
"..."
f(x)
Добавляет строку документации "..." к методу f(::Any).
"..." f(x, y = 1) = x + y
Добавляет строку документации "..." к двум Method , а именно f(::Any) и f(::Any, ::Any).
Макросы
"..." macro m(x) end
Добавляет строку документации "..." к определению макроса @m(::Any).
"..." :(@m)
Добавляет строку документации "..." к макросу с именем @m.
Типы
"..."
abstract type T1 end
"..."
mutable struct T2
...
end
"..."
struct T3
...
end
Добавляет строку документации "..." к типам T1, T2, и T3.
"..."
struct T
"x"
x
"y"
y
end
Добавляет строку документации "..." к типу T, "x" к полю T.x и "y" к полю T.y. Также применимо к типам mutable struct.
Модули
"..." module M end module M "..." M end
Добавляет строку документации "..." к Module M. Добавление строки документации над Module является предпочтительным синтаксисом, но оба эквивалентны.
"..." baremodule M # ... end baremodule M import Base: @doc "..." f(x) = x end
Документирование baremodule путём размещения строки документации над выражением автоматически импортирует @doc в модуль. Эти импорты необходимо выполнять вручную, когда выражение модуля не документировано.
Глобальные переменные
"..." const a = 1 "..." b = 2 "..." global c = 3
Добавляет строку документации "..." к Binding a, b, и c.
Binding используются для хранения ссылки на конкретное Symbol в Module без хранения сохранённого значения.
Когда определение const используется только для определения псевдонима другого определения, как это происходит с функцией div и её псевдонимом ÷ в Base, не документируйте псевдоним, а документируйте фактическую функцию.
Если псевдоним документирован, а не реальное определение, то система документации (режим ? ) не вернёт строку документации, прикреплённую к псевдониму, когда будет производится поиск реального определения.
Например, вы должны написать
"..." f(x) = x + 1 const alias = f
а не
f(x) = x + 1 "..." const alias = f
"..." sym
Добавляет строку документации "..." к значению, связанному с sym. Однако предпочтительнее документировать sym там, где оно определено.
Несколько объектов
"..." a, b
Добавляет строку документации "..." к a и b , каждый из которых должен быть документируемым выражением. Этот синтаксис эквивалентен
"..." a "..." b
Таким образом, можно документировать любое количество выражений. Этот синтаксис может быть полезным, когда две функции связаны, такие как не-изменяющие и изменяющие версии f и f!.
Код, сгенерированный макросами
"..." @m expression
Добавляет строку документации "..." к выражению, сгенерированному при развёртывании @m expression. Это позволяет документировать выражения, украшенные @inline, @noinline, @generated, или любым другим макросом, аналогично не украшенным выражениям.
Авторы макросов должны учитывать, что только макросы, генерирующие одно выражение, будут автоматически поддерживать строки документации. Если макрос возвращает блок, содержащий несколько подвыражений, то подвыражение, которое должно быть документировано, должно быть помечено с помощью макроса @__doc__.
Макрос @enum использует @__doc__ для возможности документирования Enums. Просмотр его определения должен служить примером правильного использования @__doc__.
Core.@__doc__Макрос
@__doc__(ex)
Базовый макрос, используемый для пометки выражений, возвращаемых макросом, которые должны быть документированы. Если помечено более одного выражения, то к каждому выражению применяется одна и та же строка документации.
macro example(f)
quote
$(f)() = 0
@__doc__ $(f)(x) = 1
$(f)(x, y) = 2
end |> esc
end
@__doc__ не имеет эффекта, когда макрос, который его использует, не документирован.
© 2009–2022 Jeff Bezanson, Stefan Karpinski, Viral B. Shah, and other contributors
Licensed under the MIT License.
https://docs.julialang.org/en/v1.8/manual/documentation/