Комментарии в коде как вид искусства
Приветствую всех программистов, а также сочувствующих. Кто из нас хотя бы раз в жизни не оставлял комментарии в коде? Был ли это ваш код, а может, чужой? Что за комментарии вы написали: полезные или не очень? А может, они были забавные, чтобы порадовать коллег или тимлида на следующем ревью? Давайте попробуем немного порассуждать и дать ответы на эти вопросы в формате небольшой заметки. Постараемся понять, что движет людьми, комментирующими свою программу. Упор сделаем на нестандартные, весёлые комментарии. У нас припасено для вас несколько отличных примеров. Поехали.
Введение
Все большие серьёзные исследования обычно начинаются с экскурса в историю. И чем глубже экскурс, тем лучше. Не буду отступать от традиций. Но сначала поговорим немного о предметной области — программировании и комментировании кода.
Думаю, никто не будет оспаривать того факта, что программирование — занятие творческое. Сродни писательству, с примесью технологий и философии. Современная программа, по сути, «книга» с инструкциями для компилятора, или виртуальной машины и компилятора. Несколько упрощённо, но я хочу передать основную мысль: эту «книгу» с кодом читает не только машина, но и человек. При этом человек не только смотрит, но и правит код, на что требуется много времени и сил. Поэтому, несмотря на присутствующие элементы творчества, работа программиста всё же бывает довольно рутинна. Так что эмоциональная составляющая очень важна.
Человек — существо социальное. А какое живое общение может быть с машиной? И как радостно бывает в процессе работы с кодом встретить послание самому себе с какими-то пояснениями или забавными комментариями. Ещё лучше, если послание оставил для вас другой разработчик. При этом он, возможно, и не рассчитывал, что оставляет комментарий именно для вас. Чувствуете драматизм? Вот вы уже и общаетесь. Часто — совершенно незнакомые люди. Но вот так, поплевав на ладони, взяли в руки воображаемые лопаты и как будто работаете сообща. Пробираетесь сквозь хитросплетения в коде и пытаетесь понять, как оно вообще работает. Оставляете друг другу подсказки и весёлые пасхалки. Сопричастность и командная работа в действии.
Наконец, часто требуется просто выплеснуть накопившиеся эмоции. А если эти эмоции связаны с кодом, то комментарии как раз и позволяют запечатлеть что-то наподобие:
//Dear future me. Please forgive me.
//I can't even begin to express how sorry I am.
Немного истории
Вернёмся к истории, желательно, древней, и не забудем про письменность. А что может быть древнее, чем слово? Ну, то самое, которое было в начале. Учёные, правда, утверждают, что была наскальная живопись. Это неосознанное желание даже древнего человека передать весточку собратьям или потомкам. Показать свой быт, обычаи, запечатлеть сцены охоты, праздников. Некий комментарий к своей повседневной и такой тяжёлой жизни. Да, делали как могли. Но ведь делали!
Дальше было разное. История развития письменности интересна и неоднозначна. По современным представлениям считается, что было несколько центров её зарождения. Более подробно про это можно почитать, например, в статье из Wikipedia. Но как бы там ни было, человечество проделало огромный путь от начертания простейших рисунков на глиняных табличках (Месопотамия) до современных цифровых методов генерации текста. В том числе, и текста комментариев в коде. Кстати, о технологиях: вот статья про историю развития компьютера из той же Wikipedia. Не благодарите.
И вот он — XX век с его стремительным развитием техники. Первые механические, а затем и электронные вычислительные машины. Кстати, вы знали, что Mercedes делал в том числе и арифмометры? Я не знал.
Конечно, сначала с комментариями к программам было не очень. Не думаю, что про такое вообще думали. Долгое время для собственно программирования использовали перфокарты. Конечно, можно было прямо на них написать что-то весёлое, например: «Эй, ребята, посмотрите какой тут прикольный узор из дырочек». Но кто бы оценил?
Первые компьютеры были огромные, сложные и использовались для очень серьёзных вычислений. И программисты были под стать им.
Какие уж тут весёлые комментарии? Хотя вот этого господина на следующем фото явно что-то порадовало в распечатке.
Наконец, подходим к новейшей истории, когда компьютеры получили повсеместное распространение, а программирование перестало быть таким специфическим занятием. Код программы стало очень просто создать, подправить, а также снабдить комментариями.
Главное — пользоваться этой возможностью разумно. Потому что нет ничего хуже, чем карта, которая не соответствует местности, или комментарий, который немного не так описывает код:
/**
* Always returns true.
*/
public boolean isAvailable() {
return false;
}
Но так ли часто программисты используют комментарии вообще и забавные в частности? Точной статистики нет. Ради интереса я посмотрел процент (от общего числа строк) использования комментариев в коде нашего анализатора PVS-Studio с разбивкой по языкам программирования:
- C++: около 1 082 000 строк, 15% комментариев;
- C#: около 509 000 строк, 6% комментариев;
- Java: около 80 000 строк, 16% комментариев.
Не знаю, какие выводы тут можно сделать. C# разработчики в PVS-Studio более ленивы, чем С++, и поэтому слабо комментируют код? :) Или, наоборот, их код настолько крут и интуитивно понятен, что там особо нечего пояснять? Я посмотрел некоторые комментарии, все довольно серьёзные. Ну, разве что во многих местах попалось классическое: «Не трогать!!!». Я рад, что ничто человеческое не чуждо и нашим разработчикам.
Примеры комментариев
Ну, а как всё же обстоят дела с забавными комментариями у других разработчиков? В интернете можно найти много всего на эту тему. Мне приглянулся весьма старый, но популярный вопрос, заданный на Stack Overflow: «What is the best comment in source code you have ever encountered?». Там 518 ответов. Пару примеров оттуда я уже использовал ранее в этой статье.
Сначала я планировал составить рейтинг из самых эпичных комментариев, основываясь на популярности ответов. Но, полистав ответы с низким рейтингом, понял, что и там есть довольно смешные комментарии. Поэтому я просто прошёлся по списку и выбрал некоторые понравившиеся лично мне ответы. Выборка не претендует на полноту и объективность.
Хочу заметить, что некоторые из оставленных пользователями Stack Overflow ответов очень эмоциональны и даже содержат ненормативную лексику. Поэтому я не всегда буду приводить их текст, а дам только ссылку. Но часто там содержатся действительно забавные вещи. Вот пример одного такого ответа. Также почти каждый ответ содержит обсуждение другими пользователями: вы можете переходить по ссылкам для ознакомления.
Поэтичное
Неожиданно начну с самого популярного ответа, набравшего 1460 голосов. Он содержит сразу два комментария. Первый был охарактеризован автором как «поэзия кода» (code poetry). Приведу его целиком:
/**
* For the brave souls who get this far: You are the chosen ones,
* the valiant knights of programming who toil away, without rest,
* fixing our most awful code. To you, true saviors, kings of men,
* I say this: never gonna give you up, never gonna let you down,
* never gonna run around and desert you. Never gonna make you cry,
* never gonna say goodbye. Never gonna tell a lie and hurt you.
*/
Великолепный образец привнесения мощной эмоциональной составляющей в бездушный код. Конечно, не стоит увлекаться такими посланиями на постоянной основе. Но, будучи встреченным единично, я уверен, такой комментарий способен вызвать только положительные эмоции.
Интерактивное
Второй комментарий из того же ответа добавляет частичку интерактива, немного геймифицируя рабочий процесс:
//
// Dear maintainer:
//
// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
//
// total_hours_wasted_here = 42
//
Автор указал, что не обнародовал код, в котором содержится этот счётчик. Но, даже написанный для себя, он является отличным примером побуждающего к общению комментария.
Магия кода
«Я не знаю как, но это работает». Думаю, любой программист хотя бы раз в жизни оставлял что-то подобное в своём коде. Я оставлял. Один из вариантов такого классического комментария:
//When I wrote this, only God and I understood what I was doing
//Now, God only knows
Подобные комментарии встречаются и в других ответах, например:
// Magic. Do not touch.
И ещё пример:
// I put on my robe and wizard hat...
Кстати, я тот свой «магический» код просто скопировал откуда-то, но так и не смог понять, как же он работает. :)
Непознанное
Разработчики часто переоценивают сложность своего кода. В результате появляются подобные комментарии:
/* You are not meant to understand this */
Возможно, автор и сам ничего там не понял. Ещё пример:
/**
* If you don't understand this code, you should be flipping
* burgers instead.
*/
Ну это ещё надо на код взглянуть. Наконец, немного отсылок к Данте никогда не повредит:
//Abandon all hope ye who enter beyond this point
Девятый круг.
Только попробуй!
Интересны комментарии, прямо запрещающие правку кода. Или предупреждающие о негативных последствиях этого. Пример:
// Autogenerated, do not edit. All changes will be undone.
Довольно изощрённо оставлять такое в обычном (не автоматически сгенерированном) коде, не находите? А вот более развёрнутый обстоятельный вариант совета отказаться от правок:
/*
* You may think you know what the following code does.
* But you dont. Trust me.
* Fiddle with it, and youll spend many a sleepless
* night cursing the moment you thought youd be clever
* enough to "optimize" the code below.
* Now close this file and go play with something else.
*/
Есть пример комментария, запрещающего удаление комментария:
// If this comment is removed the program will blow up
Ещё одно недвусмысленное предупреждение:
// I know the line below is wrong, but it came that way from our IP
// vendor, and the driver won't work if you "fix" it. I've had to
// revert this change 4 times now. Leave it alone, or
// I will hunt you down and hurt you
И напоследок в этом блоке:
// (c) 2000 Applied Magic, Inc.
// Unauthorized use punishable by torture, mutilation, and
// vivisection.
Работает — не трогай.
Цифровое одиночество
Не зря я столько распинался в начале про нехватку человеческого общения и эмоциональный голод. Как вам такое?
// sometimes I believe compiler ignores all my comments
Или такое?
//Mr. Compiler, please do not read this.
А вот тоже просьба, но к кому или чему?
/* Please work */
Да, программисты — они такие: изобретательны, с отличным чувством юмора, но часто одиноки и пытаются поговорить хотя бы с машиной.
Стариковское
Не менее остро стоит проблема смены поколений. Вот немного стариковского брюзжания:
* ...and don't just declare it volatile and think you've solved
* the problem. You young punks think you know what volatile
* means... why in my day we had to cast it volatile uphill
* both ways, and the code still didn't work! Whippersnappers...
Да, в наше время всё было лучше.
Отложим это на потом
Прокрастинация — вот настоящий бич современности. Конечно, программистов тоже не минула эта напасть. Пример весьма своеобразной метки TODO в коде:
// drunk, fix later
Ни в коем случае не поддерживаю такого поведения. Но все мы люди, в конце концов.
Ещё комментарий с TODO, но что-то пошло не так:
// TODO: Fix this. Fix what?
Зато есть повод поговорить. Если непонятно, что делать или что написать в комментарии:
// TODO make this work
Если не хочется писать большой комментарий:
// THE LOOP THAT DO EVERYTHING!!!!!!!
А если сейчас некогда и комментировать, то вот:
-- Comment this later
Пойду лучше посплю.
Для особо непонятливых
Куда же без комментариев в стиле Капитана Очевидность (Captain Obvious). Один из вариантов:
return 1; # returns 1
Ещё пример:
i++; // increment variable i
Да, без разъяснений тут явно не обойтись. Спасибо, Кэп.
Сделай код ещё веселее
Встретил несколько примеров конструкций, основанных на комбинации ключевых слов языка программирования, имён переменных и комментариев. Выглядит очень забавно. Вариант такого комментария:
long john; // silver
Другой пример:
long long ago; /* in a galaxy far far away */
А вот довольно двусмысленный вариант:
double penetration; // ouch
Судя по комментарию, автор тоже считает конструкцию двусмысленной. И ещё один пикантный комментарий, раз уж мы затронули эту тему:
virgin = 0; /* you're not a virgin anymore, sweety */
Главное, что не ушла в минус.
Невиновен!
За многими комментариями стоит определённая история. Например, как в следующем примере. Поэтому иногда советую переходить по ссылкам для ознакомления. Здесь вариант классического отказа от ответственности:
// I am not responsible of this code.
// They made me write it, against my will.
Ещё один отказ от ответственности (и пасхалка для следующего разработчика):
/*
This isn't the right way to deal with this, but today is my last
day, Ron just spilled coffee on my desk, and I'm hungry, so this
will have to do...
*/
return 12; // 12 is my lucky number
А мне нравится 42. Ещё встретился вариант с частичным признанием вины:
// If this code works, it was written by Paul DiLascia. If not,
// I don't know who wrote it
А ты большой хитрец, Paul. Как я уже говорил, у разработчиков тяжёлая работа:
// This is crap code but it's 3 a.m. and I need to get this working.
Зато по ночам никто не отвлекает.
Время для кофе
Не желаете немного кулинарного юмора?
} catch (PartInitException pie) {
// Mmm... pie
Ну и куда же без кофе?
// need a coffee to fix this.
Почему сельдерей увядший? Ответ по ссылке:
// Wilted celery?
Мы за здоровое питание.
Не своё — не жалко
Прокомментировать чужой код? Легко! Мне встретились примеры от довольно безобидных:
// This only exists because Scott doesn't know how to use const
// correctly
До максимально эмоциональных. Это тот самый случай, когда я приведу только ссылку. Осторожно, там много боли. Интересно, что код и комментарии обнародовал вовсе не их автор. Он случайно нашёл этот ответ на Stack Overflow, после чего решил дать разъяснения.
Свой код тоже часто комментируют весьма эмоционально. Особенно, если это Quake III и там делается техножесть. Снова привожу только ссылку.
Когда ты Кармак.
Иногда простого текста мало
Тогда для передачи всей гаммы чувств нам на помощь приходит старая добрая псевдографика. Мимо такого просто невозможно пройти:
## Safety pig has arrived!
## _
## _._ _..._ .-', _.._(`))
## '-. ` ' /-._.-' ',/
## ) \ '.
## / _ _ | \
## | a a / |
## \ .-. ;
## '-('' ).-' ,' ;
## '-; | .'
## \ \ /
## | 7 .__ _.-\ \
## | | | ``/ /` /
## /,_| | /,_/ /
## /,_/ '`-'
##
И ещё пара не менее креативных комментариев. Даю ссылку и ссылку, так как не уверен, что при копировании текста всё не разъедется.
А потом они удивляются, что исходный код такой большой.
Вместо тысячи слов
Оставлять максимально лаконичные комментарии — это здорово. Но здесь немного перестарались:
// HERE
После такого самое время отдохнуть:
// zzzzZZZZzzzz....
И пофилософствовать:
# let's pretend we are free, for a while
Зато силы на написание кода остались.
Страшное (нет)
Немного кибермистики я обнаружил в таком комментарии:
// This will save us ~0.5 sec for every user and please the machine spirits.
Дальше смешанные чувства: страшно, но интересно:
// Choose! Choose the form of the Destructor!
// The choice is made! The Traveler has come!
Главное дизассемблер не призвать.
Разное
И ещё немного комментариев, которые не удалось выделить в какую-то отдельную группу.
История релизов от разработчика. Закрытая частная версия:
//3.4 JeK My manager promised me a lap dance if I can fix this
// release
//3.5 JeK Still waiting for that dance from my manager
//3.6 JeK My manager got changed, the new manager is hairy, dont
// want the dance anymore
//3.7 Jek Got that dance, yuck!
Зато не обманули с подарком.
Вообще, комментарии обычно неотделимы от кода. Но бывают исключения:
// This comment is self explanatory.
На все случаи жизни. Я проверял.
А здесь кому-то не хватило комментариев. И он указывает на это в комментарии:
//Please comment on your source code
Когда вся твоя жизнь в комментариях.
Юридическая поддержка никогда не помешает:
/* My lawyer told me not to reveal */
Уволен!
Заключение
Напоследок хочу привести два особо ёмких комментария, в которых словно сосредоточилась вся мудрость и философия программирования. Первый:
'NO COMMENT
И второй:
// nobody read comments!
На этом у меня всё. Думаю, понятно, что тема комментариев в коде поистине неисчерпаема. Можно найти ещё миллион смешных и не очень примеров. Комментируйте свой и чужой код, не держите в себе. Делайте это весело. И пожалуйста, не забывайте исправлять грамматические ошибки в комментариях именно в день релиза (старая шутка).
Спасибо за внимание:
// good luck!
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Sergey Khrenov. Code comments as a work of art.