Большинство людей — визуалы. Они используют изображения, чтобы вникнуть в суть проблемы. А вот мэйнстримные языки программирования, напротив, основаны на текстовом представлении. Возникающую пропасть между текстом и графикой заполняют ASCII-изображения, нарисованные с помощью текстовых символов и вставленные в исходный код программы. Я их обожаю! Как-то раз я кинул клич в Twitter и мне прислали гораздо больше примеров, чем я ожидал. Спасибо всем участвовавшим. В этой теме попалось несколько прекрасных примеров, которые я собрал и разложил на категории. Для каждого изображения дается ссылка на соответствующий репозиторий.
Структуры данных
Одно из самых распространенных применений ASCII-арта в коде — наглядно показать структуру данных.
Первый пример из исходного кода LLVM:
Исходник
Расположение полей в структуре данных в Jikes RVM:
Исходник
Поворот дерева в Musl:
Исходник
Двусторонняя очередь в Rust:
Исходник
Внутренности компилятора Swift:
Исходник
Расположение элементов в заголовке Malloc:
Исходник
Конечные автоматы
Профилирование Javascript:
Исходник
RPC в Cloud Spanner:
Исходник
Состояния потока ввода-вывода:
Исходник
Логика предметной области
Поток управления в декомпилируемой программе NWScript:
Исходник
Внутренности ECC:
Исходник
Форматирование чисел:
Исходник
Квантовый контур:
Исходник
Балансировка задач управления памятью в ядре операционной системы:
Исходник
Совместимость типов (это особенно впечатляющий случай, потому что здесь ASCII-арт является кодом!)
Исходник
Формат файла DBF:
Исходник
Lookup-таблица для обработки изображений:
Исходник
Форма цветовой функции:
Исходник
Структура URL:
Исходник
«Краткая» справка по отмене операций в emacs:
Исходник
Примечание переводчика: по ссылке еще очень много подобных графиков
Геометрия
Контроль высоты в бортовом компьютере Apollo (!!!):
Исходник
Разбитие изображения на сегменты:
Исходник
Траектории бумеранга в Nethack:
Исходник
Отрисовка границ элемента в CSS:
Исходник
Дерево квадрантов:
Исходник
Управление скоростью работы станка:
Исходник
Скроллинг веб-страниц:
Исходник
Надеюсь, вам понравилось!
Дополнительный пример от переводчика:
График интерполяции значения:
Исходник
Комментарии (23)
reticular
19.02.2019 12:19+1` /)/)
=(';')=
(").(")…catsmile
19.02.2019 20:48+1Персонально я в своих комментариях использовал
(_*_)
и
?\_(?)_/?
Как правило это было связано с форматом респонса API.
Keyten
20.02.2019 15:29--MEOW--/>? ?
?????| ?_? _|
? ???/`? _x ?
?? ? /??? ? |
??? /? ??? ?
?/?|?? |?|?|
?| (??__?_)_)
?\??
tuxi
19.02.2019 14:13Аж слезу пустил. Моя первая (не первая по счету, но первая сделанная на персоналке) программа была предназначена для создания из ASCII символов заставок для использования их в других программах. ДВК-2М и Pascal. Называлась S.M.I.T. Управление клавиатурой, сохранение в готовый код на Паскале.
surly
20.02.2019 13:52Аналогично, но для Robotron-1715. Преобразования в исходники не было, только рисование, сохранение, загрузка.
Lpndn
19.02.2019 19:26Давно думал, как элегантно внедрять схемы в текстовую документацию, а про ASCII совсем позабыл. Спасибо!
mechatroner
19.02.2019 19:35Спасибо за популяризацию интересной идеи!
Но вот только зачем было в качестве КДПВ ставить первое изображение? И в оригинальной статье его нет.
vyo
19.02.2019 21:36Порой и сам код тянет на ASCII-арт. Чего хоть стоит паттерн для захвата двух последовательно идущих символов в lua:
"(.)(.)"
(пример настоящий).
mafia8
19.02.2019 22:09Файл сжать и перевести в uue. Поместить в исходный код с некоторым текстом, плагин редактора заметит этот текст, достанет файл, развернёт и покажет.
DROS
19.02.2019 23:20О, сам пользуюсь такой методикой для описания формата хранения например или какого хитровыкрученного алгоритма. Очень удобно. Правда «рисую» ручками, а не софтом.
KvanTTT
20.02.2019 00:07+1Возникла идея. Графы можно описывать с помощью graphviz, а блок-схемы — с помощью mermaid. Ведь можно сделать поддержку рендера этих объектов прям внутри IDE! Описывать графы и блок-схемы нужно будет в комментах с помощью привычных для Markdown маркеров ```dot, ```mermaid. Да и вообще можно сделать рендер и маркдауна тоже.
Исходники останутся "диффабельным", но при этом в IDE будут рендериться наглядные картинки.
Danik-ik
20.02.2019 08:41Ну, добрая четверть примеров похожа на текстовый вариант выхлопа plantuml (поверх graphviz работает). Кмк, лучший uml формат для хранения в git. И плагин к Идее есть. И локально запускается, не только онлайн.
И если бы мне захотелось вставлять в код uml диаграммы в комментариях, я бы делал это автогенерацией из исходника на plantuml
MacIn
20.02.2019 00:21А то как же.
Вот иллюстрация работы класса с «устаревающим» набором данных:
{ TSlinky } // mW0__ <-data items // _0_|3 ^ // ___|2 | // ___|1 | // __|0 | //t <------------------+
Вспоминается документация к СМ ЭВМ и программам для ОСРВ, которая была отпечатана, судя по всему, на «барабанных» АЦПУ и там было полно таких схем, как в статье, объясняющих структуры данных, программных и аппаратных комплексов, интерфейсов…
sergey-gornostaev
20.02.2019 06:58+1В коде Netty (javadoc'ах если быть точным) это активно используется:
The following diagram describes how I/O events are processed by ChannelHandlers in a ChannelPipeline typically. An I/O event is handled by either a ChannelInboundHandler or a ChannelOutboundHandler and be forwarded to its closest handler by calling the event propagation methods defined in ChannelHandlerContext, such as ChannelHandlerContext.fireChannelRead(Object) and ChannelOutboundInvoker.write(Object). I/O Request via Channel or ChannelHandlerContext | +---------------------------------------------------+---------------+ | ChannelPipeline | | | \|/ | | +---------------------+ +-----------+----------+ | | | Inbound Handler N | | Outbound Handler 1 | | | +----------+----------+ +-----------+----------+ | | /|\ | | | | \|/ | | +----------+----------+ +-----------+----------+ | | | Inbound Handler N-1 | | Outbound Handler 2 | | | +----------+----------+ +-----------+----------+ | | /|\ . | | . . | | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()| | [ method call] [method call] | | . . | | . \|/ | | +----------+----------+ +-----------+----------+ | | | Inbound Handler 2 | | Outbound Handler M-1 | | | +----------+----------+ +-----------+----------+ | | /|\ | | | | \|/ | | +----------+----------+ +-----------+----------+ | | | Inbound Handler 1 | | Outbound Handler M | | | +----------+----------+ +-----------+----------+ | | /|\ | | +---------------+-----------------------------------+---------------+ | \|/ +---------------+-----------------------------------+---------------+ | | | | | [ Socket.read() ] [ Socket.write() ] | | | | Netty Internal I/O Threads (Transport Implementation) | +-------------------------------------------------------------------+
Magn
21.02.2019 00:41Да, было дело.
Хотя лично мне кажется, что некоторые из представленных в посте «комментариев» тянут на страницу в нормальной документации. ASCII-арт комментарий должен помочь быстро понять суть, если её можно передать простой картинкой, но не более. Имхо, конечно.
KhodeN
21.02.2019 11:32В тестах RxJS используются не только для документирования, но и для входных и ожидаемых данных (событий в потоках).
DSolodukhin
А чем можно рисовать такие диаграммы, как в примере с компилятором swift?
impwx Автор
Похоже на AsciiFlow.
dlinyj
sudo apt install asciio && asciio
n00ker
можно накидать схему в plantUml и сгенерировать ascii код по ней.