Написание документации
Elixir рассматривает документацию как объект первого класса. Документация должна быть легко написана и легко прочитана. В этом документе вы узнаете, как писать документацию на Elixir, охватывая такие конструкции, как атрибуты модулей, практические рекомендации по стилю и doctests.
Markdown
Документация Elixir написана с использованием Markdown. В интернете есть множество руководств по Markdown, мы рекомендуем руководство с GitHub в качестве точки входа:
Атрибуты модуля
Документация на Elixir обычно прикрепляется к атрибутам модуля. Давайте рассмотрим пример:
defmodule MyApp.Hello do
@moduledoc """
This is the Hello module.
"""
@moduledoc since: "1.0.0"
@doc """
Says hello to the given `name`.
Returns `:ok`.
## Examples
iex> MyApp.Hello.world(:john)
:ok
"""
@doc since: "1.3.0"
def world(name) do
IO.puts("hello #{name}")
end
end
Атрибут @moduledoc используется для добавления документации к модулю. @doc используется перед функцией для предоставления документации к ней. Помимо вышеперечисленных атрибутов, @typedoc также может использоваться для прикрепления документации к типам, определенным в рамках типовpec. Elixir также позволяет добавлять метаданные к документации, передавая список ключевых слов в @doc и аналогичные функции.
Аргументы функции
При документировании функции имена аргументов выводятся компилятором. Например:
def size(%{size: size}) do
size
end
Компилятор выведет этот аргумент как map. Иногда вывод будет неоптимальным, особенно если функция содержит несколько разделов с соответствием аргумента на разные значения каждый раз. Вы можете указать правильные имена для документации, объявив только заголовок функции в любой момент перед реализацией:
def size(map_with_size)
def size(%{size: size}) do
size
end
Метаданные документации
Elixir позволяет разработчикам прикреплять произвольные метаданные к документации. Это делается путем передачи списка ключевых слов в соответствующий атрибут (например, @moduledoc, @typedoc, и @doc). Часто используемые метаданные — это :since, которые отмечают, в какой версии был добавлен конкретный модуль, функция, тип или обратный вызов, как показано в примере выше.
Еще одни распространенные метаданные — :deprecated, которые выводят предупреждение в документации, объясняя, что его использование не рекомендуется:
@doc deprecated: "Use Foo.bar/2 instead"
Обратите внимание, что ключ :deprecated не выдает предупреждение, когда разработчик вызывает функции. Если вы хотите, чтобы код также выводил предупреждение, вы можете использовать атрибут @deprecated:
@deprecated "Use Foo.bar/2 instead"
Метаданные могут иметь любой ключ. Инструменты документирования часто используют метаданные для предоставления большего количества данных читателям и обогащения пользовательского опыта.
Рекомендации
При написании документации:
Сохраняйте первый абзац документации кратким и простым, обычно одной строкой. Инструменты, такие как ExDoc, используют первую строку для генерации сводки.
-
Ссылки на модули должны быть полными.
Markdown использует обратные кавычки (
`) для цитирования кода. Elixir расширяет это, автоматически генерируя ссылки, когда ссылаются на имена модулей или функций. По этой причине всегда используйте полные имена модулей. Если у вас есть модуль под названиемMyApp.Hello, всегда ссылайтесь на него как на`MyApp.Hello`и никогда как на`Hello`. Ссылки на функции должны быть по имени и арности, если они локальные, как в
`world/1`, или по модулю, имени и арности, если они относятся к внешнему модулю:`MyApp.Hello.world/1`.Ссылки на
@callbackдолжны начинаться сc:, как в`c:world/1`.Ссылки на
@typeдолжны начинаться сt:, как в`t:values/0`.Начинайте новые разделы с заголовков второго уровня Markdown
##. Заголовки первого уровня предназначены для имён модулей и функций.Размещайте документацию перед первым разделом многораздельных функций. Документация всегда относится к функции и арности, а не к каждому разделу.
Используйте ключ
:sinceв метаданных документации, чтобы отмечать добавление новых функций или модулей в ваш API.
Doctests
Рекомендуется включать примеры в документацию, часто под собственным заголовком ## Examples. Чтобы примеры не устаревали, тестовый фреймворк Elixir (ExUnit) предоставляет функцию под названием doctests, которая позволяет тестировать примеры в документации. Doctests работают путем анализа фрагментов кода, начинающихся с iex> из документации. Подробнее об этом можно прочитать по адресу ExUnit.DocTest.
Обратите внимание, что doctests имеют ограничения. Когда функция не может быть протестирована с помощью doctest, потому что она зависит от состояния или побочных эффектов, разработчикам рекомендуется включать примеры непосредственно без подсказки iex>.
Документация ≠ Комментарии к коду
Elixir рассматривает документацию и комментарии к коду как разные понятия. Документация — это явный контракт между вами и пользователями вашего Application Programming Interface (API), будь то сторонние разработчики, коллеги или вы сами в будущем. Модули и функции всегда должны быть задокументированы, если они являются частью вашего API.
Комментарии к коду предназначены для разработчиков, читающих код. Они полезны для обозначения улучшений, оставляния заметок (например, почему вы были вынуждены прибегнуть к обходному решению из-за ошибки в библиотеке) и т. д. Они связаны с исходным кодом: вы можете полностью переписать функцию и удалить все существующие комментарии к коду, и она будет продолжать работать одинаково без каких-либо изменений в поведении или документации.
Поскольку к частным функциям нельзя получить доступ извне, Elixir выведет предупреждение, если у частной функции есть атрибут @doc и отбросит его содержимое. Тем не менее, вы можете добавлять комментарии к коду в частные функции, как и в любой другой код, и мы рекомендуем разработчикам делать это, когда они считают, что это добавит полезную информацию для читателей и разработчиков такого кода.
Наконец, будьте осторожны с избыточными комментариями к коду, такими как те, которые описывают то же самое, что и код:
# Total is the sum of the batch and individual entries total = batch_sum + individual_sum
В общем, документация — это контракт с пользователями вашего API, которые могут не иметь доступа к исходному коду; в то время как комментарии к коду предназначены для тех, кто взаимодействует напрямую с исходным кодом. Вы можете узнать и выразить различные гарантии о своем программном обеспечении, разделив эти два понятия.
Скрытие внутренних модулей и функций
Помимо модулей и функций, предоставляемых библиотеками как часть их публичного интерфейса, библиотеки также могут реализовывать важную функциональность, которая не входит в их API. Хотя к этим модулям и функциям можно получить доступ, они предназначены для внутреннего использования в библиотеке, и поэтому они не должны иметь документации для конечных пользователей.
Для удобства Elixir позволяет разработчикам скрывать модули и функции от документации, установив @doc false для скрытия конкретной функции или @moduledoc false для скрытия всего модуля. Если модуль скрыт, вы даже можете документировать функции в модуле, но сам модуль не будет отображаться в документации:
defmodule MyApp.Hidden do
@moduledoc false
@doc """
This function won't be listed in docs.
"""
def function_that_wont_be_listed_in_docs do
# ...
end
end
Если вам не нужно скрывать весь модуль, вы можете скрыть функции индивидуально:
defmodule MyApp.Sample do @doc false def add(a, b), do: a + b end
Однако имейте в виду, что @moduledoc false или @doc false не делают функцию частной. Вышеупомянутую функцию все еще можно вызвать как MyApp.Sample.add(1, 2). Более того, если MyApp.Sample импортируется, функция add/2 также будет импортирована в вызывающий код. По этим причинам будьте осторожны при добавлении @doc false к функциям, вместо этого используйте один из этих двух вариантов:
Переместите недокументированную функцию в модуль со значением
@moduledoc false, например,MyApp.Hidden, гарантируя, что функция не будет случайно раскрыта или импортирована. Помните, что вы можете использовать@moduledoc falseдля скрытия всего модуля и при этом документировать каждую функцию с помощью@doc. Инструменты по-прежнему проигнорируют модуль.Начните имя функции с одного или двух подчеркиваний, например,
__add__/2. Функции, начинающиеся с подчеркивания, автоматически обрабатываются как скрытые, хотя вы также можете быть явными и добавить@doc false. Компилятор не импортирует функции с ведущими подчеркиваниями, и они намекают любому, кто читает код, на их предполагаемое частное использование.
Code.fetch_docs/1
Elixir хранит документацию внутри предопределенных блоков в байт-коде. Документация не загружается в память при загрузке модулей, вместо этого ее можно прочитать из байт-кода на диске с помощью функции Code.fetch_docs/1. Недостаток заключается в том, что модули, определенные в памяти, например, те, которые определены в IEx, не могут получить доступ к своей документации, так как они не записывают свой байт-код на диск.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.15.4/writing-documentation.html