Spec-Zone.ru › Elixir 1.14

Написание документации

Elixir рассматривает документацию как элемент первого класса. Это означает, что документация должна быть лёгкой для написания и лёгкой для чтения. В этом документе вы узнаете, как писать документацию на Elixir, охватывая такие конструкции, как атрибуты модуля, практические рекомендации по стилю и doctests.

Markdown

Документация Elixir написана с использованием Markdown. В интернете существует множество руководств по Markdown, мы рекомендуем руководства GitHub в качестве отправной точки:

  • Основные синтаксис написания и форматирования
  • Мастерство Markdown

Атрибуты модуля

Документация на 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 рассматривает документацию и комментарии к коду как разные понятия. Документация — это явный контракт между вами и пользователями вашего 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

В случае, если вы не хотите скрывать весь модуль, вы можете скрывать функции индивидуально:

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 хранит документацию внутри предопределённых блоков в байткоде. К нему можно получить доступ из Elixir, используя функцию Code.fetch_docs/1. Это также означает, что к документации обращаются только при необходимости, а не при загрузке модулей виртуальной машиной. Единственный недостаток заключается в том, что модули, определённые в памяти, такие как те, которые определены в IEx, не могут иметь доступ к своей документации, так как их байткод не записывается на диск.

← Предыдущая страница Синтаксис Юникода
Следующая страница → Изменения в Elixir v1.14

© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.14.1/writing-documentation.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API