Написание документации
Elixir рассматривает документацию как первоклассный гражданин. Это означает, что документация должна быть легко написана и легко прочитана. В этом документе вы узнаете, как писать документацию на Elixir, охватывая такие конструкции, как атрибуты модулей, практические рекомендации по стилю и тесты-документации.
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 также можно использовать для прикрепления документации к типам, определённым как часть типовпек. 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.
Тесты-документации
Мы рекомендуем разработчикам включать примеры в свою документацию, часто в заголовке ## Examples. Чтобы примеры не устаревали, фреймворк тестирования Elixir (ExUnit) предоставляет функцию тестов-документации, которая позволяет разработчикам тестировать примеры в своей документации. Тесты-документации работают путём анализа фрагментов кода, начинающихся с iex> в документации. Вы можете узнать больше об этом по адресу ExUnit.DocTest.
Обратите внимание, что тесты-документации имеют ограничения. Когда невозможно протестировать функцию с помощью тестов-документации, потому что она зависит от состояния или побочных эффектов, мы рекомендуем разработчикам включать примеры непосредственно без подсказки iex>.
Документация != Комментарии к коду
Elixir рассматривает документацию и комментарии к коду как разные понятия. Документация — явный договор между вами и пользователями вашего API (Application Programming Interface), будь то сторонние разработчики, коллеги или ваше будущее «я». Модули и функции должны быть всегда документированы, если они являются частью вашего 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 Однако помните, что добавление @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 хранит документацию внутри предопределённых фрагментов в байткоде. К ней можно получить доступ из Elixir, используя функцию Code.fetch_docs/1. Это также означает, что документация извлекается только при необходимости, а не при загрузке модулей виртуальной машиной. Единственный недостаток заключается в том, что модули, определённые в памяти, такие как те, что определены в IEx, не могут иметь доступ к своей документации, так как их байткод не записан на диск.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.8.2/writing-documentation.html