code doc
This commit is contained in:
parent
afdbcc5795
commit
ff28324e0b
331
content/posts/2022/crystal/documenting-code.md
Normal file
331
content/posts/2022/crystal/documenting-code.md
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
---
|
||||||
|
title: "Документирование кода Crystal"
|
||||||
|
date: 2022-10-13T21:22:47+03:00
|
||||||
|
draft: true
|
||||||
|
tags: [crystal, tutorial, development]
|
||||||
|
---
|
||||||
|
|
||||||
|
## О статье
|
||||||
|
|
||||||
|
Это мой вольный перевод оригинальной
|
||||||
|
[статьи](https://crystal-lang.org/reference/1.6/syntax_and_semantics/documenting_code.html)
|
||||||
|
из документации по **Crystal**.
|
||||||
|
|
||||||
|
> Если есть желание внести правки, пожалуйста пишите.
|
||||||
|
> Если остались вопросы, также пишите.
|
||||||
|
|
||||||
|
## Документирование кода
|
||||||
|
|
||||||
|
Документация для функций API может быть написана в комментариях к коду, непосредственно предшествующих определению соответствующей функции.
|
||||||
|
|
||||||
|
По умолчанию все общедоступные методы, макросы, типы и константы считаются частью документации API.
|
||||||
|
|
||||||
|
Команда компилятора `crystal docs` автоматически извлекает документацию API и создает веб-сайт для её представления.
|
||||||
|
|
||||||
|
## Ассоциация
|
||||||
|
|
||||||
|
Комментарии должны располагаться непосредственно над документируемым объектом.
|
||||||
|
Последовательные строки комментариев объединяются в один блок комментариев.
|
||||||
|
Любая пустая строка разрывает связь с задокументированным объектом.
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# Этот комментарий не связан с классом.
|
||||||
|
|
||||||
|
# Первая строка документации для класса Unicorn.
|
||||||
|
# Вторая строка документации для класса Unicorn.
|
||||||
|
class Unicorn
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
## Форматирование
|
||||||
|
|
||||||
|
Комментарии документации поддерживают
|
||||||
|
[Markdown](https://daringfireball.net/projects/markdown/) форматирование.
|
||||||
|
|
||||||
|
Первый абзац комментария к документу считается его кратким изложением.
|
||||||
|
В нем должно быть кратко определено назначение и функциональность.
|
||||||
|
|
||||||
|
Дополнительные сведения и инструкции по использованию должны содержаться в последующих параграфах.
|
||||||
|
|
||||||
|
Напрмиер:
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# Возвращает количество рогов, которые есть у этого единорога.
|
||||||
|
#
|
||||||
|
# Всегда возвращает `1`.
|
||||||
|
def horns
|
||||||
|
1
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Рекомендуется использовать в написании комментариев настоящее время от третьего лица:
|
||||||
|
"_Возвращает количество рогов, которые есть у этого единорога_".
|
||||||
|
|
||||||
|
## Разметка
|
||||||
|
|
||||||
|
### Linking
|
||||||
|
|
||||||
|
Ссылки на другие функции API могут быть заключены в знаки апострофа.
|
||||||
|
Они автоматически преобразуются в ссылки на соответствующую функцию.
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
class Unicorn
|
||||||
|
# Создает новый экземпляр `Unicorn`.
|
||||||
|
def initialize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Правила поиска применяются те же, что и в Crystal code. К функциям в задокументированном в настоящее время пространстве имен можно получить доступ по относительными именами:
|
||||||
|
|
||||||
|
* На методы экземпляра ссылаются с помощью хэш-префикса: `#horns`.
|
||||||
|
* На методы класса ссылаются с помощью префикса точки: `.new`.
|
||||||
|
* На константы и типы ссылаются по их имени: `Unicorn`.
|
||||||
|
|
||||||
|
На объекты в других пространствах имен ссылаются с помощью полного пути к типу: `Unicorn#horns`, `Unicorn.new`, `Unicorn::CONST`.
|
||||||
|
|
||||||
|
Различные перегрузки метода могут быть идентифицированы по полной сигнатуре `.new(name)`, `.new(name, age)`.
|
||||||
|
|
||||||
|
### Параметры
|
||||||
|
|
||||||
|
При обращении к параметрам рекомендуется писать их название курсивом (`*выделено_курсивом*`):
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# Создает единорога с указанным количеством *рогов*.
|
||||||
|
def initialize(@horns = 1)
|
||||||
|
raise "Не единорог" if @horns != 1
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### Примеры кода
|
||||||
|
|
||||||
|
Примеры кода могут быть размещены в блоках кода Markdown.
|
||||||
|
Если языковой тег не указан, блок кода считается кодом на языке Crystal.
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# Пример:
|
||||||
|
# ```
|
||||||
|
# unicorn = Unicorn.new
|
||||||
|
# unicorn.horns # => 1
|
||||||
|
# ```
|
||||||
|
class Unicorn
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Чтобы обозначить блок кода как обычный текст, он должен быть явно помечен тегом.
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# Вывод:
|
||||||
|
# ```plain
|
||||||
|
# "Я единорог"
|
||||||
|
# ```
|
||||||
|
def say
|
||||||
|
puts "Я единорог"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Также можно использовать другие языковые теги.
|
||||||
|
|
||||||
|
Чтобы отобразить значение выражения внутри блоков кода, используйте `# =>`.
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
1 + 2 # => 3
|
||||||
|
Unicorn.new.speak # => "Я единорог"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Предупреждения
|
||||||
|
|
||||||
|
Поддерживаются несколько ключевых слов-предупреждений для визуального выделения проблем,
|
||||||
|
заметок и/или возможных проблем.
|
||||||
|
|
||||||
|
* `BUG`
|
||||||
|
* `DEPRECATED`
|
||||||
|
* `EXPERIMENTAL`
|
||||||
|
* `FIXME`
|
||||||
|
* `NOTE`
|
||||||
|
* `OPTIMIZE`
|
||||||
|
* `TODO`
|
||||||
|
* `WARNING`
|
||||||
|
|
||||||
|
Ключевые слова с предупреждением должны быть первыми в соответствующей строке и должны быть написаны заглавными буквами. Необязательное завершающее двоеточие предпочтительнее для удобства чтения.
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# Заставляет единорога говорить в STDOUT
|
||||||
|
#
|
||||||
|
# NOTE: Хотя единороги обычно не разговаривают, этот особенный
|
||||||
|
# TODO: Проверить, спит ли единорог, и вызвать исключение, если он не может говорить
|
||||||
|
# TODO: Создать другой метод `speak`, который принимает и печатает строку
|
||||||
|
def speak
|
||||||
|
puts "Я единорог"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Заставляет единорога говорить в STDOUT
|
||||||
|
#
|
||||||
|
# DEPRECATED: Используйте `speak`
|
||||||
|
def talk
|
||||||
|
puts "Я единорог"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Компилятор неявно добавляет некоторые предостережения к комментариям документации:
|
||||||
|
|
||||||
|
* Аннотация `@[Deprecated]` добавляет предупреждение `DEPRECATED`.
|
||||||
|
* Аннотация `@[Experimental]` добавляет предупреждение `EXPERIMENTAL`.
|
||||||
|
|
||||||
|
## Директивы
|
||||||
|
|
||||||
|
Директивы сообщают генератору документации, как обращаться с документацией для конкретной функции.
|
||||||
|
|
||||||
|
### `ditto`
|
||||||
|
|
||||||
|
Если два последовательно определенных объекта имеют одинаковую документацию,
|
||||||
|
`:ditto:` можно использовать для копирования одного и того же комментария к документу
|
||||||
|
из предыдущего определения.
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# Возвращает количество рогов.
|
||||||
|
def horns
|
||||||
|
horns
|
||||||
|
end
|
||||||
|
|
||||||
|
# :ditto:
|
||||||
|
def number_of_horns
|
||||||
|
horns
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Директива должна быть в отдельной строке, но дополнительная документация
|
||||||
|
может быть добавлена в других строках.
|
||||||
|
Директива `:ditto:` просто заменяется содержимым предыдущего комментария к документу.
|
||||||
|
|
||||||
|
### `nodoc`
|
||||||
|
|
||||||
|
Общедоступные функции могут быть скрыты из документов API с помощью директивы `:nodoc:`.
|
||||||
|
Частные и защищенные функции всегда скрыты.
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# :nodoc:
|
||||||
|
class InternalHelper
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Эта директива должна быть первой строкой в комментарии к документу.
|
||||||
|
Начальный пробел необязателен.
|
||||||
|
Следующие строки комментариев могут быть использованы для внутренней документации.
|
||||||
|
|
||||||
|
### `inherit`
|
||||||
|
|
||||||
|
_Смотри [Наследование документации](#наследование-документации)_.
|
||||||
|
|
||||||
|
## Наследование документации
|
||||||
|
|
||||||
|
Когда метод экземпляра не имеет комментария документации,
|
||||||
|
но метод с такой же сигнатурой существует в родительском типе,
|
||||||
|
документация наследуется от родительского метода.
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
abstract class Animal
|
||||||
|
# Возвращает имя из `self`.
|
||||||
|
abstract def name : String
|
||||||
|
end
|
||||||
|
|
||||||
|
class Unicorn < Animal
|
||||||
|
def name : String
|
||||||
|
"единорог"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Документация для `Unicorn#name` была бы:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Описание скопировано из класса `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.
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
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` была бы:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Some documentation specific to *id*'s usage within `Child`.
|
||||||
|
|
||||||
|
Some documentation common to every *id*.
|
||||||
|
```
|
||||||
|
|
||||||
|
> Наследование документации работает только с методами экземпляра, не являющимися конструкторами.
|
||||||
|
|
||||||
|
## Полный пример
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
# 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
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user