Blog/content/posts/2022/crystal/documenting-code.md

12 KiB
Raw Blame History

title date draft tags
Документирование кода Crystal 2022-10-13T21:22:47+03:00 true
crystal
tutorial
development

О статье

Это мой вольный перевод оригинальной статьи из документации по Crystal.

Если есть желание внести правки, пожалуйста пишите.
Если остались вопросы, также пишите.

Документирование кода

Документация для функций API может быть написана в комментариях к коду, непосредственно предшествующих определению соответствующей функции.

По умолчанию все общедоступные методы, макросы, типы и константы считаются частью документации API.

Команда компилятора crystal docs автоматически извлекает документацию API и создает веб-сайт для её представления.

Ассоциация

Комментарии должны располагаться непосредственно над документируемым объектом.
Последовательные строки комментариев объединяются в один блок комментариев.
Любая пустая строка разрывает связь с задокументированным объектом.

# Этот комментарий не связан с классом.

# Первая строка документации для класса Unicorn.
# Вторая строка документации для класса Unicorn.
class Unicorn
end

Форматирование

Комментарии документации поддерживают Markdown форматирование.

Первый абзац комментария к документу считается его кратким изложением. В нем должно быть кратко определено назначение и функциональность.

Дополнительные сведения и инструкции по использованию должны содержаться в последующих параграфах.

Напрмиер:

# Возвращает количество рогов, которые есть у этого единорога.
#
# Всегда возвращает `1`.
def horns
  1
end

Рекомендуется использовать в написании комментариев настоящее время от третьего лица:
"Возвращает количество рогов, которые есть у этого единорога".

Разметка

Linking

Ссылки на другие функции API могут быть заключены в знаки апострофа. Они автоматически преобразуются в ссылки на соответствующую функцию.

class Unicorn
  # Создает новый экземпляр `Unicorn`.
  def initialize
  end
end

Правила поиска применяются те же, что и в Crystal code. К функциям в задокументированном в настоящее время пространстве имен можно получить доступ по относительными именами:

  • На методы экземпляра ссылаются с помощью хэш-префикса: #horns.
  • На методы класса ссылаются с помощью префикса точки: .new.
  • На константы и типы ссылаются по их имени: Unicorn.

На объекты в других пространствах имен ссылаются с помощью полного пути к типу: Unicorn#horns, Unicorn.new, Unicorn::CONST.

Различные перегрузки метода могут быть идентифицированы по полной сигнатуре .new(name), .new(name, age).

Параметры

При обращении к параметрам рекомендуется писать их название курсивом (*выделеноурсивом*):

# Создает единорога с указанным количеством *рогов*.
def initialize(@horns = 1)
  raise "Не единорог" if @horns != 1
end

Примеры кода

Примеры кода могут быть размещены в блоках кода Markdown.
Если языковой тег не указан, блок кода считается кодом на языке Crystal.

# Пример:
# ```
# unicorn = Unicorn.new
# unicorn.horns # => 1
# ```
class Unicorn
end

Чтобы обозначить блок кода как обычный текст, он должен быть явно помечен тегом.

# Вывод:
# ```plain
# "Я единорог"
# ```
def say
  puts "Я единорог"
end

Также можно использовать другие языковые теги.

Чтобы отобразить значение выражения внутри блоков кода, используйте # =>.

1 + 2             # => 3
Unicorn.new.speak # => "Я единорог"

Предупреждения

Поддерживаются несколько ключевых слов-предупреждений для визуального выделения проблем, заметок и/или возможных проблем.

  • BUG
  • DEPRECATED
  • EXPERIMENTAL
  • FIXME
  • NOTE
  • OPTIMIZE
  • TODO
  • WARNING

Ключевые слова с предупреждением должны быть первыми в соответствующей строке и должны быть написаны заглавными буквами. Необязательное завершающее двоеточие предпочтительнее для удобства чтения.

# Заставляет единорога говорить в STDOUT
#
# NOTE: Хотя единороги обычно не разговаривают, этот особенный
# TODO: Проверить, спит ли единорог, и вызвать исключение, если он не может говорить
# TODO: Создать другой метод `speak`, который принимает и печатает строку
def speak
  puts "Я единорог"
end

# Заставляет единорога говорить в STDOUT
#
# DEPRECATED: Используйте `speak`
def talk
  puts "Я единорог"
end

Компилятор неявно добавляет некоторые предостережения к комментариям документации:

  • Аннотация @[Deprecated] добавляет предупреждение DEPRECATED.
  • Аннотация @[Experimental] добавляет предупреждение EXPERIMENTAL.

Директивы

Директивы сообщают генератору документации, как обращаться с документацией для конкретной функции.

ditto

Если два последовательно определенных объекта имеют одинаковую документацию, :ditto: можно использовать для копирования одного и того же комментария к документу из предыдущего определения.

# Возвращает количество рогов.
def horns
  horns
end

# :ditto:
def number_of_horns
  horns
end

Директива должна быть в отдельной строке, но дополнительная документация может быть добавлена в других строках. Директива :ditto: просто заменяется содержимым предыдущего комментария к документу.

nodoc

Общедоступные функции могут быть скрыты из документов API с помощью директивы :nodoc:. Частные и защищенные функции всегда скрыты.

# :nodoc:
class InternalHelper
end

Эта директива должна быть первой строкой в комментарии к документу. Начальный пробел необязателен. Следующие строки комментариев могут быть использованы для внутренней документации.

inherit

Смотри Наследование документации.

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

Когда метод экземпляра не имеет комментария документации, но метод с такой же сигнатурой существует в родительском типе, документация наследуется от родительского метода.

Пример:

abstract class Animal
  # Возвращает имя из `self`.
  abstract def name : String
end

class Unicorn < Animal
  def name : String
    "единорог"
  end
end

Документация для Unicorn#name была бы:

Описание скопировано из класса `Animal`

Возвращает имя из `self`.

The child method can use :inherit: to explicitly copy the parent's documentation, without the Description copied from ... text. :inherit: can also be used to inject the parent's documentation into additional documentation on the child.

Пример:

abstract class Parent
  # Некоторая документация, общая для каждого *id*.
  abstract def id : Int32
end

class Child < Parent
  # Some documentation specific to *id*'s usage within `Child`.
  #
  # :inherit:
  def id : Int32
    -1
  end
end

Документация для Child#id была бы:

Some documentation specific to *id*'s usage within `Child`.

Some documentation common to every *id*.

Наследование документации работает только с методами экземпляра, не являющимися конструкторами.

Полный пример

# A unicorn is a **legendary animal** (see the `Legendary` module) that has been
# described since antiquity as a beast with a large, spiraling horn projecting
# from its forehead.
#
# To create a unicorn:
#
# ```
# unicorn = Unicorn.new
# unicorn.speak
# ```
#
# The above produces:
#
# ```text
# "I'm a unicorn"
# ```
#
# Check the number of horns with `#horns`.
class Unicorn
  include Legendary

  # Creates a unicorn with the specified number of *horns*.
  def initialize(@horns = 1)
    raise "Not a unicorn" if @horns != 1
  end

  # Returns the number of horns this unicorn has
  #
  # ```
  # Unicorn.new.horns # => 1
  # ```
  def horns
    @horns
  end

  # :ditto:
  def number_of_horns
    horns
  end

  # Makes the unicorn speak to STDOUT
  def speak
    puts "I'm a unicorn"
  end

  # :nodoc:
  class Helper
  end
end