Как стать автором
Обновить

Комментарии 221

В некотором случае обилие структурированных комментариев удобно для автоматического создания документации (Sandcastle или Doxygen и т.п.). Но зачастую обильные комментарии очень плохо влияют на читабельность кода, иногда лучше назвать функцию не GFrN, a GetFriendName и избавиться сразу от лишних комментариев.
смотрю на сгенерированную таким образом доку по kohana 3 и понимаю, что лучше бы такой доки не было, все-равно всегда лезу в код смотреть.
Лучше молчать и казаться глупым, чем открыть рот и окончательно развеять все сомнения. © М. Твен

Иными словами, эта документация генерируется не для разработчиков, использующих в данном случае Kohana в своих разработках, а для документирования кода при доработке самого фреймворка.
Не для разработчиков? А для кого?
Не для разработчиков, использующих Kohana для создания сайтов, а для авторов Kohana, занимающихся доработкой самого Kohana.
Так понятно, спасибо. Но:
1. Все-таки по ссылке дока для пользователей
2. Если мне, как пользователю легче заглянуть в код, то, имхо, для разработчиков тои подавно.
3. Если имеется ввиду, что разработчикам будущегометода надо знать, что он будет делать — для этого есть название метода и тесты. А для фреймворка особо важны понятные названия и хорошие тесты
Как ты юзеров не назови: хоть девелоперами хоть мантейнерами хоть еще кем, они так и останутся юзерми. поэтому User Guide. Может хочешь для себя доработать пресловутую Кохану — на здоровье. Просто в данном случае ты дорабатываешь ее ядро (для чего и нужен этот тип документации), а не систему, основанную на ней (а в этом случае такая документация становится практически бесполезной).

И еще, что касается документирования кода в формате JavaDoc — это очень полезная штука, помогает экономить огромную кучу в времени, особенно в разработке корпоративных приложений. А уж формат вывода генерации — это дело десятое, можно в конце концов написать свой генератор, который будет выдовать документацию по API в самом удобном для вас формате.
Довольно часто User Guide и Developer/Contributer Guide библиотек/фреймворков разделены.
А вот мне нравиться как сделана документация yii по тому же принципу.
Угу. По принципу «без комментариев».
Вот интересный пример с которым буквально на днях столкнулся:
www.yiiframework.com/doc/api/1.1/CHtml#activeDropDownList-detail
Please refer to listOptions on how this data is used to generate the list options. Note, the values and labels will be automatically HTML-encoded by this method.

Все описание этого listOptions = «Generates the list options.». То есть дословно нам говорят, пожалуйста, посмотрите исходники лист оптионс, чтобы понят как тут входные параметры будут использоваться :\

Для этого можно применить @tutorial, к примеру дабы показать как использовать функцию. Еще раз, дело не в том что не все разработчики достаточно ознакомлены с JD или документатор не поддерживает тех или иных «тегов». А скорее в том что это принятый формат и ничего не мешает писать красивую и удобную документацию как например здесь developer.android.com/reference/packages.html или здесь dev.sencha.com/deploy/dev/docs/
Я не к самой системе комментарий написал, а к тому что yii явно не пример хорошей документации :\
Я так понял, что refer to listOptions призывает обратится к описанию функции listOptions, то есть сюда www.yiiframework.com/doc/api/1.1/CHtml#listOptions-detail
Хотя может и этой документации в Вашем случае мало, я с YII не работал. Но документации там больше чем «Generates the list options.»
там только htmlOptions расписан. Но он к довольно часто встречается в других функциях и с ним та проблем как раз не было.
>иногда лучше назвать функцию не GFrN, a GetFriendName

я бы сказал «всегда». За такие названия надо руки с корнем отрывать
Хм. А почему? Мне казалось, что лучше назвать публичную функцию очевидным образом, чем писать доку по ней?
Ой, сорри. Неправильно прочитал
Оторвите руки полному составу Bell Labs 70-х годов.
У них была объективная причина — называлась перфокарты
/* no comment */
Примеры кода с комметами лучше чем без них. А ответ на топик «Комментарии в коде — полезные, бессмысленные, вредные?» я увидел только 'бессмысленные'. Где остальные?
Пример вредного комментария:

/**
 * Always returns true.
 */
public boolean isAvailable() {
    return false;
}
Такие комментарии практически неизбежны. Иногда при правке кода банально «руки не доходят» до правки комментариев. Но это редкость. А в основном комментарии — сугубо положительная вещь.
Даже в «бессмысленных» комментариях я не вижу никакого зла.

Автор пишет про «так еще и комментарий отъедает место». Мы, к счастью, уже давненько не используем 40-строчные MDA мониторы и борьба за место таким образом выглядит не только неубедительной, но и «бессмысленной».
Борьба за место очень даже имеет смысл на любом размере монитора. На 15 дюмах это шесть методов против трех на экран, а на 30 — двенадцать против шести. Ну и еще куча причин
Даже на 42 дюймах, вопрос уже идет не о размере экрана, а охвате самих глаз :)
У меня 37" и ничего, охватывается. При том, что мне приходится сидеть довольно близко. К тому же проблемы возникают скорее по ширине, а не высоте.
Впрочем, по-моему, от 23" увеличение размера экрана при том же разрешении ни на что не влияет. Шрифты меньше 10 уже напрягают своей корявостью, а не размером.
вы программируете на телевизоре? :)
Дома — да. Именно на том, который на фото в профиле.:)
Йопт. Я думал, что я пошутил… а оказалось, нет…
Круто же! :)
Подожди еще 5 лет и так немалая часть будет говорить ;)
да через 5 лет я себе сам такой телек вместо монитора куплю )))
На современном FullHD мониторе помещается меньше 60 строк, так что прогресс не так велик, как Вам кажется. Методы и классы, не влезающие в экран — отнюдь не редкость, даже без комментариев. Бессмысленные комментарии уменьшают объём полезной информации и ухудшают понимание кода.
Нормальные IDE давно умеют сворачивать doc комментарии в одну строку.
И на каждый однострочный геттер будет строка комментария, давая соотношение код/комментарии 1:1. ;) Впрочем, я имел в виду не doc, потому что это как раз вещь необходимая, чтобы метод был в документации.
Иногда код правится не только в IDE, а и в Notepad++, например. Бывает и такое :)
Не нужно быть IDE чтобы уметь сворачивать комментарии. Виндовским редакторам (да и остальным тоже) ещё многому можно научиться у vim.
да не только у vim. Даже простенький kwrite умеет сворачивать блоки, подсвечивать синтаксис и показывать примитивное автодополнение
Потому, что документация к коду не является частью языка, если бы она являлась, то вот такие бяки проверял бы компилятор.
Бессмысленные комментарии не несут никакой пользы, однако с течением времени могут превращаться в вредные комментарии из-за рассинхронизации этих самых комментариев и кода, так что без них будет лучше чем с ними. Ну и код захламляют как ниже сказано, когда ведь его читаешь невольно читаешь и комментарии (вдруг что полезное?).
/**
 * Always returns true.
 */
public boolean isAvailable() {
    return false;
}


#define false true;

fixed!
Тем не менее этот комментарий заставляет посмотреть в историю изменений файла, чтобы понять, зачем теперь возвращается false, хотя изначально планировалось возвращать true. Так что не такой уж он и бесполезный.
Это если несоответствие будет замечено. А если второй разработчик просто бегло взглянет на комментарий чтобы понять, что делает функция (или вообще код открывать не будет, а данный комментарий высветится в тултипе при появлении этой функции в списке авто-комплита), то будет ориентироваться на то, что всегда возвращается «true». После этого он потратит час-другой (в лучшем случае) на отладку (ибо программа будет вести себя совсем не так, как задумывалось), и когда наконец-то доберётся дебаггером до этой функции, то… не завидую я автору правки, приведшей к противоречию комментария и реального поведения функции, особенно если он сидит за соседним столом :)
Какие в книжке были примеры такие и написал.
Мне кажется что не стоит писать код, формальный комментарий к которому больше :)

А если серьезно, то я через пару недель уже не помню свой код, посему к функции приписываю хотя бы строчку-другую описания. И параметры неплохо бы описать, если они не имеют говорящих имен.
Просто IDE мне показывает doc и уже не надо прыгать в исходники.

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

По поводу последнего примера надо бы так:
// FIXME: Хак, траляля [name]
// описание
и пользовать вкладку tasks
FIXME тоже плохая идея, вместо того, чтобы писать комментарий, надо брать и фиксить.
иногда без этого никак)
бывает и так, что нельзя пофиксить прямо сейчас, что в статье и написано. Я например недавно такой хак делал, когда напоролся на мелкий баг в Qt (даже не совсем баг, скорее отсутствие достаточно тривиальной, но нужной фичи). Багрепорт запостил, но пока починят в Qt, возможности сделать нормально не будет.
А fixme как раз чтобы потом вспомнить, где чинить, когда возможность появится.
Абсолютно не согласен. Если переключатся постоянно с задачи на задачу теряется время и контекст. Так что лучше делать задачу за задачей, а там где нужно отвлекаться — ставить Fixme.
> И параметры неплохо бы описать, если они не имеют говорящих имен.
Если параметры не имеют говорящих имён, их надо не описать, а переписать.
ну имя переменной на всю ширину экрана не комильфо, опять же не все переменные можно переписать
Во всю ширину, конечно, перебор. Но на практике больше 32х символов нужно в очень редких случаях. Ширина FullHD-монитора около 180 символов. Даже если забить его доками с деревом классов и т.п. останется достаточно.
Можно пример параметра, который можно описать в комментарии, но нельзя переписать?
API сформировавшийся в те времена, когда FullHD был редкостью (да и сейчас они далеко не у всех)
Замена названий параметров API не порушит, так что пример не подходит.
Реально FullHD нужен очень редко, 1280 вполне достаточно. Если у кого-то монитор слабее, его надо менять в любом случае. Подстраиваться под пользователей нетбуков в данной области по-моему не стоит.
Смотря в каком языке, если используются именованные параметры то порушит
С этим согласен. Надо было сразу так и написать.
ага, попробуйте потаскать свой fullHD в сумке :)
FullHD в сумку, да, не влезет. Там я таскаю 1280х800. Тесновато, но что ж делать.
Однако, писание программ в полевых условиях — это вообще отдельный жанр.
Дело не в том что влезет или нет, дело в том что влом.
нормальное окружение поднимается уже почти на любом буке с интернетом, так какого я буду сидеть за столом, если я с таким же успехом могу сидеть где-нить еще?

Упираться в размер экрана и в их количество вообще — глупость. Если улучшать рабочее место, то и двух 24 дюймовых экранов мало и может быть и трех будет мало, не пробывал. А вот ноута почему-то хватает :)
Кому как. Мне ноута не хватает. Хабр читать и то тесно. Я предпочитаю располагаться с комфортом за столом, в удобном кресле да с большими наушниками. И на дачу FullHD монитор таскаю. А вот два монитора мне почему-то не нравится, я даже на ноуте обычно экран отключаю.
32 — уже много, лучше 5-10. А если 10 символов не хватает — значить надо делать еще короче.
чем длиннее переменные тем хуже код читается.
Если код можно читать, а не расшифровывать, то, конечно, чем короче — тем лучше. Я счётчики в цикле тоже обычно называю просто I. Но к параметрам это не относится. Сокращать можно только локальные переменные.
надеюсь, следующим будет пост о вреде этого поста. вы пытаетесь накормить голодающих дав им рыбу, вместо того чтобы научить пользоваться сеть.

уже всё хорошо написано в книге Стива Макконнелла «Совершенный код», лучше прочесть её, чем питаться объедками.

та все статьи на Хабре такие. можно прочитать огромные талмуды по JavaScript, PHP, C#, деталям OOP и архитектуры, и т.д. и т.п. и не нужны статьи на Хабре, ни одна.
есть классическая литература без прочтения которой страшно к коду подпускать. а такой огрызок принесёт больше вреда от непонимания картины вцелом, чем пользы.

хотя, да, здесь зачастую за много буков ругают.
Zorkus, добавь пожалуйста, ссылку на макконела, кто-то да одолеет.
Все, кто интересуется темой про «Совершенный код», «Рефакторинг» и остальное как минимум знают. Но любителей избыточного комментирования я встречаю регулярно. В том числе среди гуру.
>>Zorkus, добавь пожалуйста, ссылку на макконела, кто-то да одолеет

Добавил.
НЛО прилетело и опубликовало эту надпись здесь
> надеюсь, следующим будет пост о вреде этого поста. вы пытаетесь накормить голодающих дав им рыбу, вместо того чтобы научить пользоваться сеть.

Как и почти вся продукция компании Microsoft, и ничего — живёт и процветает. ;)
Microsoft учит пользоваться сетью, даёт рыбу и учит готовить. Я фанат их продукции. Кстати, и Макконнелл связан с данной компанией.
> Microsoft учит пользоваться сетью

И какая часть пользователей может, хотя бы, разбить жёсткий диск на разделы при установке? А «готовят» вообще прикладным софтом, а не ОС. MS тут ни при чём _почти_.

> Я фанат их продукции.

Борѝтесь. Фанатизм мешает объективно оценивать качество технологий.

У MS особый вид сетей: нажал на кнопку — выскочила, наловила рыбы и в ведёрко сложила. А потом сама в футляр убирается. Вот на кнопку нажимать они и учат.
«Мало того что сам код, по сути, синтетический, + из-за Java Code Conventions растягивается три строчки ради удобочитаемости, так еще и комментарий отъедает место.»
я правильно понял что печетесь не об удобочитаемости а об экономии места? чем вам code conventions то не угодил?
каким бы коротким не был геттер/сеттер, все-же это метод и сплющивать его до 1 строчки тоже плохо по ряду причин
меня тоже эти джава доки по делу и без дела безумно утомляют в коде. так у меня на странице вмещается 7 методов, а с Джава-доками — 3.
Откройте для себя фолдинг?
В нормальных редакторах он есть.
прыгание по методам через ктрл-клик? знаю и использую. я пользуюсь Нетбинсом и много вещей там есть. и что? все-равно куда приятнее семь методов на экране, чем три
Нет. Сворачивание методов/комментариев/блоков кода. Тогда на экране они не занимают лишнее место.
все-равно разражают…
тогда когда меняешь код — забываешь поменять доку, она ведь свёрнутая и не обращаешь на неё внимание.
в идее есть включенная по умолчанию опция — сворачивать простые сеттеры/геттеры. проблем с «растягиванием кода на три строчки» нет
НЛО прилетело и опубликовало эту надпись здесь
«Мало того что сам код, по сути, синтетический, + из-за Java Code Conventions растягивается три строчки ради удобочитаемости, так еще и комментарий отъедает место.»
я правильно понял что печетесь не об удобочитаемости а об экономии места? чем вам code conventions то не угодил?
каким бы коротким не был геттер/сеттер, все-же это метод и сплющивать его до 1 строчки тоже плохо по ряду причин»

Я не призываю умещать метод в одну строку. Мое замечание относилось к тому, что если бы в java были свойства (в Groovy, например, есть, и под ту же JVM), такие сеттеры геттеры вообще бы не надо было писать. И соответственно, комментов бы к ним не было :)
НЛО прилетело и опубликовало эту надпись здесь
Ваше право, конечно (если начальника это устраивает), однако, когда Вам вдруг потребуется что-то изменить, обращения придётся исправлять по всему проекту.
Сам я всё пишу руками и часто в одну строку, но у меня C++, а не java.
НЛО прилетело и опубликовало эту надпись здесь
Для C++ тоже есть умные IDE :)

см. VisualAssist, например
я как-то пожалел, что у меня не было геттеров и сеттеров)
тогда вы правы, согласен
>Кроме того — комментарий здесь занимает три строки в редакторе кода.
Не спорю, комментарий бесполезен, но грамотная IDE его автоматически свернет, будет всего лишь одна строчка.
При прочтении заметки сразу вспомнилась тема на StackOverflow про лучшие комментарии в коде :)
Угу, шикарные там вещи:
// 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 = 37

//When I wrote this, only God and I understood what I was doing
//Now, God only knows

// I'm sorry.
вторая цитата моя любимая)

так же как:

// Magic. Do not touch.


/*
 * 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

НЛО прилетело и опубликовало эту надпись здесь
Комментарии в коде это зло. Если коду нужны комментарии то надо подумать о качестве кода и качестве именования классов, методов и переменных. Исключение — взаимодействие со сторонними библиотеками, имеющими «причуды».
Ну, эт Вы через чур. Конечно, что сделано должно быть понятно из названия переменных и методов без комментариев, но почему это сделано именно так в нетривиальных местах надо пояснять обязательно. Также нелишне кратко указывать на подводные камни, из-за которых не сработает более простой и/или эффективный алгоритм, иначе придётся регулярно исправлять последствия такой оптимизации.
Дык я в своем сообщении про это и написал про «причуды». Причуды могут возникнуть в 95% извне (при условии что у вах нормальные разработчики и бюджета хватает). За что минусов накидали, хм… Останусь верен себе — комментарии в коде указывают на неоднозначность кода. В 95% случаев :)
Но я имел в виду вовсе не сторонние библиотеки, а особенности именно того кода и алгоритма, в котором находится комментарий.
Странно, что человека заминусовали. Код должен быть очевидным в большинстве своем, а длинные комментарии не в APIшных классах скорее снижают читаемость, в APIшных впрочем тоже, но тут уж увы, никуда от этого не убежишь.
Лучше переменные называть понятными именами, а не так как принято в «венгерской нотации».
Когда в коде много комментариев и он явно не является частью API или учебным, это наводит на определенные мысли.
Очевидный код можно написать максимум для бизнес-логики. Любой нетривиальный код нельзя написать так, чтобы было всё очевидно. Примеры? Напишите-ка мне RB дерево так чтобы было всё ясно без единого комментария.
Класс с комментарием сверху — «Это реализация красно-черного дерева, пишу свою, т.к. реализация в либе такой-то мне не подходит, описание структуры данных смотри там то»?
Вывод: вы ни разу не писали реализацию RB дерева. Посмотрели бы хотя бы на Википедии как реализуется, например, добавление. Сначала идёт пол-экрана текста объяснения, затем пять строк кода. И так 5 случаев. Если этих комментариев в коде не будет, вы никогда не закончите даже отладку, потому что настоящая реализация и примеры кода в книге не совпадают никогда (по различным причинам). Поэтому просто поставить ссылку на Кормена не получится.
Вывод неправильный.

В википедии дается объяснение, чтобы любой мог прочитать и понять досконально алгоритм. Вы предлагаете эти комментарии скопипастить в свой код? Увольте. Реализация сама по себе весьма компактна. Вот ссылку на википедию и давайте в хедере класса.
сорри за съехавший болд(
Скопировать полностью? Ни в коем случае. Но в 2-3 строках дать объяснение каждого случая — обязательно.

Вы спорите о том, чего не знаете.
О чем?
Возьмите и напишите RB-tree без комментариев в коде. Напишите тесты, отладьте и потом скажете сколько дней у вас это заняло.

Или возьмите любую подпрограмму из LAPACK, выбросьте комментарии и попробуйте хотя бы сказать, какой алгоритм в ней реализован (я уже не говорю о том, чтобы понять каждую строку реализации).

А потом будете спорить.
Чего вы кстати прицепились к РБ-три? Это далеко не самый сложный алгоритм и не такой уж громоздкий в реализации.
Во-первых, потому что это вполне доступный для каждого программиста пример — никому не нужно объяснять зачем нужны деревья. Во-вторых, это часто используемая и широко известная структура данных и мне никто не смог бы ответить «откуда вы откопали этот алгоритм, давайте ссылку на описание, там всё проще чем думаете». И в третьих, для того, чтобы не прыгать между разными примерами в комментариях.
Ок, принято.
Имхо, чем в комментариях трактаты писать, лучше в папку пакета с вашей кастомной реализацией положить README или добавить в код ссылку на некий документ с описанием того, что, как и почему. Всё-таки, код — не место для подробного описания, да и не даёт тех возможностей, которые даёт та же Вики. Отключите картинки и формулы в Вики — многие алгоритмы потеряют понятность.
Я может на самом деле увлекся, да.

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

1. реализация должна иметь ссылку на книгу + надежный веб-источник (типа википедии), может на какой нибудь ACM paper, где расписаны все детали (например, на статью Укконена про быстрое построение суффиксного дерева).

А в коде должны быть помечены места, где реализация (а не общая идея!) нетривиальна. Ну грань может быть тонкой, да.
Часто вам приходится нетривиальный код писать? К тому же к нетривиальным кускам лучше действительно прикладывать книжечку с описанием, почему так.
Вернусь к вашему примеру. Нетривиальный код это не вот это:
((void(*)(void))0)();
Тут как раз всё понятно (если не понятно — то значит кто-то не дочитал учебник по Си).

Нетривиальный код там, где алгоритмы нетривиальны. И да, часто приходится.
Говорю, к нетривиальным алгоритмам нужно давать ссылку на описание, а в коде только отсылки к нему вставлять, а иначе придется прорываться через сотни комментов, чтобы суть увидеть.
Нетривиальный алгоритм никогда не реализуется точно так как в книге по различным причинам: эффективность реализации (в книгах упрощают для объяснения), изменение алгоритма под задачу и так далее.
Я просто это к тому веду, что если будет 20 строчек комментов потом 3 строчки кода потом еще 20 строчек комментов, то читать будет неудобно. Плюс в комментариях форматирование текста малость неудобно. Лучше уж пусть будет ссылка на htmlку с описанием и кусками кода из алгоритма.
Совершенно верно.

Вот комментарий вида — «используется битсет вместо другой структуры данных для производительности» писать имеет смысл. Писать комментарии о том, как работает «дерево вообще, по книжке» — не надо.
В данном случае следует описывать отличия.
Однако, если описание алгоритма можно изложить в комментариях компактно (конечно, благодаря правильным названиям переменных, типов и функций), то имеет смысл это сделать, а не отсылать к источникам, чтобы не сбивать фокус внимания. Кроме того их может элементарно не оказаться под рукой в нужный момент.
В любом случае главное — баланс. Также стоит учитывать целевую аудиторию: для студентов удобнее один вариант, а для гуру — другой.
> Странно, что человека заминусовали.
За категоричность ИМО.
Если по проекту генерируется ява(и прочий)док, то комменты, даже глупые, всегда нужны
НЛО прилетело и опубликовало эту надпись здесь
Это не комментарии, это документация кода. Они несут несколько иные задачи — описание интерфейса против описания реализации.
В каментах лучше всего записывать основные идеи алгоритма или реализации на человеческом языке. Я пишу каменты так, как-будто объясняю код другому человеку.
Недавно столкнулся со следующим кодом (фрагмент из реализации ProfileProvider):
// Magic. Do not touch.
var profilesFound = profiles.GetProfiles(x => !(
    x.ApplicationName != applicationName ||
    !(usernameToMatch == null ||
        x.Username == usernameToMatch) ||
    !(userInactiveSinceDate == null ||
        x.LastActivityDate <= (DateTime)userInactiveSinceDate) ||
    !(authenticationOption == ProfileAuthenticationOption.Anonymous &&
        x.IsAnonymous ||
      authenticationOption == ProfileAuthenticationOption.Authenticated &&
        !x.IsAnonymous)
));
Как ни странно — все работает. Но, судя по вашей статье, не совсем понятно — это полезный или вредный комментарий. Вроде бы места не много занимает.
Тот же макконнел кажется писал — «если вы не понимаете досконально, как работает ваш код, скорее всего, на самом деле он и не работает так, как надо».
А где здесь магия? По мне так это обычный перебор.
Магия она вот
{((void(*)(void))0)();} // что-то из черной магии

или даже вот
*reinterpret_cast<int *>(&showFlags) = behavior.value("showFlags", 0xfffffff);

Даже это можно причислить к колдунству, правда скорее к белой магии. И то код вполне очевиден, хоть и написан в традициях Александреску

template<typename T, int N, X = int>
Q_INLINE_TEMPLATE X strToEnum(const T &str, const char *(&strings)[N])
{
for(int i=0;i<=N;i++) {
if(QLatin1String(strings[i]) == str)
return static_cast(i);
}
return static_cast(-1);
}

Гребаный хабрапарсер надругался над шаблонами
template<typename T, int N, X = int>
Q_INLINE_TEMPLATE int strToEnum(const T &str, const char *(&strings)[N])
{
  for(int i=0;i<=N;i++) {
    if(QLatin1String(strings[i]) == str)
      return static_cast<X>(i);
  }
  return static_cast<X>(-1);
}


* This source code was highlighted with Source Code Highlighter.
use <source lang="cpp">...</source>, Luke!
Согласен — код читается нормально. С другой стороны я что-то подобное с двойным отрицанием не написал бы с первого раза.

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

    if (!!(conf = qobject_cast<Conference *>(unit))) {
      foreach (ChatUnit *u, conf->lowerUnits()) {
        if (Buddy *buddy = qobject_cast<Buddy*>(u))
          addContact(buddy);
      }
    }


* This source code was highlighted with Source Code Highlighter.
conf — указатель? Тогда зачем тут двойное отрицание?
Указатель да :) В принципе можно и без двойного отрицания здесь обойтись ;)
руки оторвать за такой код надо
Отрывать руки можно только за пример номер два, ибо лучше пользоваться обычным static_cast'ом. Пример номер один — это вполне себе валидный способ перезагрузки на контроллерах, такой код можно найти например в сырцах Linux'а.
В примере номер 3 есть одна бага, в рабочем варианте она исправлена уже, но тем не менее, решил запостить сюда код с ней. Найдете?
PS
Виноват, кажется не на ту ветку комментов посмотрел
Во-первых, надо убрать линее отрицание и правильно сформатировать:
// Magic. Do not touch.
var profilesFound = profiles.GetProfiles(x => (
    x.ApplicationName == applicationName && (
		usernameToMatch == null || x.Username == usernameToMatch
	) && (
		userInactiveSinceDate == null ||
		x.LastActivityDate <= (DateTime)userInactiveSinceDate
	) && (
		(x.IsAnonymous && authenticationOption == ProfileAuthenticationOption.Anonymous)
			||
		(!x.IsAnonymous && authenticationOption == ProfileAuthenticationOption.Authenticated)
	)
));


Во-вторых-повыносить куски кода в методы. Не знаю, что это за язык, но как-то так:

isCorrectApplication (x) {
	return x.ApplicationName == applicationName;
}

isUsernameMatched (x) {
	return usernameToMatch == null || x.Username == usernameToMatch;
}

isUserActive (x) {
	return userInactiveSinceDate == null ||
		x.LastActivityDate <= (DateTime)userInactiveSinceDate;
}

isAuthenticationAllowed (x) {
	return isAnonymousAuthentication(x) || isProfileAuthentication(x);
}

isAnonymousAuthentication (x) {
	return (x.IsAnonymous && authenticationOption == ProfileAuthenticationOption.Anonymous);
}

isProfileAuthentication (x) {
	return (!x.IsAnonymous && authenticationOption == ProfileAuthenticationOption.Authenticated)   
}


А теперь написать нормальный, легкоподдерживаемый, очевидный с первого взгляда код. Тот код — отличный пример того, когда надо провести рефакторинг, но ни в коем случае не комментирование.
И да, надавать по рукам тому джуниору, который решил выебнуться, как он круто расставляет операторы сравнения.
var profilesFound = profiles.GetProfiles(x => (
    isCorrectApplication(x) &&
	isUsernameMatched(x)    &&
	isUserActive(x)         &&
	isAuthenticationAllowed(x) 
));
Вы чертовски правы. Паттерн Specification — в данном случае — is a must.
А вообще, страшно, когда один кусок кода хардкодно знает о таком большом количестве различных условий.

Я бы реализовал примерно так (пишу на родном PHP):
$profileProvider->addChecker(new AppIdentityChecker($profileProvider->getApp(), $app));
$profileProvider->addChecker(new UserIdentityChecker($profileProvider->getUser(), $user));
$profileProvider->addChecker(new UserStatusChecker($user));
$authChecker = AuthCheckerFactory::createChecker($profileProvider->getAuthType(), $user);
$profileProvider->addChecker($authChecker);

if ($profileProvider->check()) {
    ...
}
Такого очень много в говнокоде. В итоге весь код выглядит как «лучше не трогать». Приходится засучивать рукава и из «магии» делать нечто понятное, простое и структурированное.
И вообще не люблю, когда все javadoc'и запихнуты в хедер, неудобно потом вручную искать нужный метод. Лучше уж в cpp файл класть.
> когда все javadoc'и запихнуты в хедер,… Лучше уж в cpp файл класть

разрыв шаблона как он есть.
Как бы тебе сказать то…
формат javadoc и в С++ многие юзают ;)
Ну я как бы в курсе ;) но звучит все равно жутко ;)
Вспомнилось:

#define true false; // с… ки, чтоб вы за… бались дебажить!
Боян…
#define CRASH_SOMETIMES 1/(rand() % 100);
Фред Брукс отлично написал в своей книге, что обычно полезные комментарии не пишут дабы не брать не себя ответственность за дизайн неочевидных моментов в коде, поэтому чаще всего комментируется то, что не может быть оспорено, типа комментарий «This method gets comment» для метода getComments.

Предпочитаю логичный код вместо комментариев к нелогичному ;)
Ссылка на книгу:
Фредерик Брукс. Мифический человеко-месяц или Как создаются программные системы. www.ozon.ru/context/detail/id/83760/
если, кто о ней не знает.

Кстати «Совершенный код» нужно читать очень осторожно взвешивая применимость конвенций, которые в нём постулируется, к том или иному языку или технологии. Часто работал с адептами этой книги, размахивающими факелами, не вникая в причину отхода от той или иной конвенции по вполне понятным причинам.

А Фаулеровский «Рефакторинг» must read всем, кто программирует… даже изредка :)
Кстати информацию о хаках лучше все же писать. Потому что – блин, ну мы все программисты здесь и все понимаем, что не всегда есть физическая возможность сделать правильно, красиво, пройти серию code review и получить на выходе совершенный код, иногда нужно сделать прямо сейчас, вчера, и хак — это единственное, что можно сделать быстро. В этом случае критически важно написать, почему было принято такое неочевидное решение.

Ну разумеется, по уму, надо еще и открыть баг на самого себя с описанием этой проблемы. Но эту часть часто, увы, пропускают ;-)
Я так понял, комментарий про хак — это как раз пример очевидно полезного комментария. Единственно, чего там недостаёт, это мыслей автора, о том как надо реализовывать функциональность когда нет жёсткого цейтнота.
Это, увы, на момент хака часто крайне неочевидно :(
В этом случае надо указать, что не знаешь, как правильно эо реализовывать.
Кстати факт, я обычно так и пишу. Плюс какие-то свои мысли на эту тему.
>/**
>*
>* Some description.
>* @param paramName1 paramName1
>* @param paramName2 paramName2
>* @param paramName3 paramName3
>* @return the name of user
>*/
doxygen же, комментарии читаем в сгенеренной доккументации. Так что их бесполезность вами переоценена.
Кроме примера по doxygen поддержу и коментаторов, которые акцентирубт внимание на том, что описание методов (функций) поддерживается IDE. Описал в doc-блоке функцию — не мучаешься каждый раз в исходниках в последовательности и типах данных её аргументов и её выводе: IDE сама подсветит справку по интересующей функции бзе перехода к исходному коду.

Значит, экономим время на разработку и на создание, в итоге, продукта :)
нормальное IDE без этих костылей сигнатуру метода правильно распарсить должно
Уважаемый Gorthauer87, если вы работаете с языком с динамической типизацией (php, Ruby), то скорее всего для многих типов данных вам описание типов в методе (прежде всего я говорю о скалярных типах в том же php) просто не светит. В отличие от, скажем, сходного описания процедуры или функции в Pascal, запись function(int $myInt){...} в php просто не будет парситься корректно интерпретатором.

Да и варианты «на вход» в таких языках могут быть разные (число или булево значение; int или расписанный по стандарту timestamp в виде строки)… Без doc-блок в таких случаях — никуда.
Я же помню делал функции в php со вполне явной сигнатурой. Но впрочем да, согласен, для таких языков придется дописывать в доках описание аргументов и возращаемого значения.
Описывать в сигнатуре можно переменные, являющиеся массивами и экземплярами классов. Это действительно работает в php 5. Но с integer, boolean и string — увы.

Я сам одно время был сторонником «самодокументированного кода», но если метод умеет чуть больше, чем описывается двумя-тремя словами (которые можно «впихнуть» в camelCase), а имена переменных ввода/вывода могут оказаться неочевидными и, возможно, поддерживать разные типы — без описаний получается в итоге каша и масса вариантов для неочевидностей. Поэтому сейчас стараюсь писать комментарии разумных размеров :)
Добавлю ещё полезность описания возвращаемого значения в виде int|FALSE, помогающее вспомнить о том, что результат надо сравнивать с помощью оператора идентичности, а не равенства.
> «public String getUserName(String paramName1, int paramName2, int paramName2)»
Для начала — нельзя называть параметры «paramNameX».

> «достаточно прочитать 6 строк комментария вместо 80 строк кода метода с бизнес-логикой»
Хмм, что же это вы за бизнес-логику такую пишете, что методы по 80 строк? Давнооо такого не встречалось, даже в сложных проектах, чтобы один метод…
В основном это вызовы других методов + пустые строки + скобки блоков и всякие IF-ы.
80 строк? нихреновая лапша ифов.
Ифов там 3 штуки
хорошо. всяких ифов — три строки из восьмидесяти.

В основном это вызовы других методов + пустые строки + скобки блоков и всякие IF-ы.

все методы в основном это вызовы других методов + пустые строки + скобки блоков и всякие IF-ы.

я очень согласен с вашим топиком, но метод на 80 строк — это зло похлеще любых комментариев кроме редчайших исключений.
Вот вот! И я офигеваю :)
Ну как сказать. Это код DataMining -driven планировщика который рассчитывает корректировки заказов на ближайшие дни на основании последних данных о продажах, которые приходят через интеграцию от магазинов ритейлинговой сети. Как-то так :)
и что?
Ничего, просто контекст дал задачи.
Ну хорошо, вы сами начали :) Точнее, продолжаете. Уже просто спортивный интерес одолевает, что там за метод такой. Можете его сбросить на какой-нибудь Pastebin на ревью? :) Очень уж хочется посмотреть.
То есть, 3 ифа — 6 строк, пустых строк — штук 30, и еще больше 40 — вызовы других методов???
И это только getUserName? :)
Ну, я утрирую же, чего вы. Код на 80 строк это часто нормально. Считайте что нормальный IF занимает строк 5 каждый. Вот уже 15 строк…
15 строк — это нормально. а 80 строк — не нормально.
Ну, если утрируете — тогда нет вопросов, а то тут есть за что уцепиться :)

Просто весь метод getUserName — это return userRepository.Get(user.Id).Name;, ну или ненамного больше, а все остальное — нарушение SRP.
мне даже интересно. зачем может понадобится 80!!! строк, чтобы получить имя пользователя?
Ага, тоже интересно, я потому уже код этого мифического метода попросил уже там, выше в каментах :)
аа, ну разумеется 80 строк это не получение имени пользователя!!! :)

80 строк это код метода какого-нибудь контроллера, см. выше:

«DataMining -driven планировщика который рассчитывает корректировки заказов на ближайшие дни на основании последних данных о продажах, которые приходят через интеграцию от магазинов ритейлинговой сети»
Главный недостаток комментариев, имхо, необходимость их ручной синхронизации с кодом и никто (в отличии от, например, тестов при изменении логики или транслятора при изменении сигнатуры) не напомнит о том, что код изменился, а комментарий нет. Потому стараюсь писать так, чтобы в них не было необходимости
Или же их нужно сделать частью языка и опять же проверять формально.
Именно. Для .NET мы пользуемся StyleCop и подсказками ReSharper'а (и их же генераторами комментов), для других платформ не знаю.

Впрочем, код на Руби, например, или Питоне, вообще не представляю в обилии комментариев в Doc-стиле. Там такой миниатюрный, простой, понятный и крутой код, что его сам по себе не хочется загромождать комментариями :)
в любой IDE есть возможность сворачивать комменты в раскрываемый список
habrahabr.ru/blogs/development/108985/#comment_3457775

все-равно разражают…
тогда когда меняешь код — забываешь поменять доку, она ведь свёрнутая и не обращаешь на неё внимание.
По-моему, это как раз главная проблема обширных комментариев — необходимость постоянно синхронизировать с кодом и разброд, если этим пренебречь.
Наверное, надо их писать к релизу и не сливать в development-ветку. :)
Автор топика пытается оправдать собственную лень? :)
Нет разумеется. Я и сам за собой замечаю, что иногда по привычке начинаю писать комментарии ко всему подряд. Потом одергиваю себя и начинаю их удалять. :)
На самом деле, лучше такая крайность, чем обратная. В любой современной IDE комментарии можно сворачивать, и они не мешают читать или редактировать код. А вот их отсутствие куда ужаснее сказывается на последующей поддержке проекта.
нет. лучше, чтобы комментариев не было, чем они были излишними и неправильными.
Я полагаю, вы не работали с большими объемами трудночитаемого макаронного кода, в котором разобраться можно исключительно с помощью команды grep.
я регулярно работаю с большими объемами кода, в том числе разбирал «магию».
например, очень хорошо разобрался в магии, которая используется в Мутулз.
но практически ни разу не встретил комментария, который описал мне что-то лучше, чем описывает сам код.
Там нет никакой магии и код очень легок для понимания :) Популярные библиотеки типа jquery, mootools, tinymce и другие — написаны опытными разработчиками в понятной форме. Магия начинается там, где писали программисты, которых либо сложно назвать профессионалами, либо они через чур начинают мудрить там, где это абсолютно не требуется. Код, в котором тонны костылей, которые пораждают тысячи непонятных зависимостей и «недокументированных возможностей» — вот где будет полезна любая зацепка в виде комментария.

Поверьте, любым комментарием человек хочет пояснить то, что он написал, а не что-то абстрактное, что пришло ему в голову. Из опыта могу сказать, что ошибки в комментариях возникают чаще всего в наборе параметров или описании излишней/чрезмерной функциональности — что является, обычно, следствием рефакторинга данного участка кода. Но суть в 95% случаев можно легко уследить. Повторюсь, речь идет о коде, который описывает реально сложную запутаную логику и функциональность, а не банальный набор set/get.
такие разработчики, о которых вы рассказываете комментируют так само, как пишут код. правильно комментировать, наверное, еще тяжелее, чем правильно писать код. потому что если ты напишешь говно вместо кода — его может забраковать компилятор/интерпретатор, а вот если напишешь говно вместо комментария — проверять его не будет кому

комментарии бывают полезны, но это исключения.
Есть такое понятие как «ревью» кода, который не допускается на продакшен без проверки другим разработчиком, который, в свою очередь, может оценить насколько комментарий уместен, а код логичен и понятен. Я сам всегда сложные места в коде обсуждаю с коллегами и стараюсь указывать на ошибки и некорректные решения других разработчиков.

> комментарии бывают полезны, но это исключения.
Это настолько абсурдное заявление, что я даже не знаю, что вам ответить… комментарии, документация и прочие сопутствующие вещи — незаменимая и неотъемлемая часть жизненного цикла любого софтверного продукта.
Если есть ревью кода, то код будет нормальный, а не «тонны костылей, которые пораждают тысячи непонятных зависимостей и «недокументированных возможностей»».
Тут такая интересная зависимость:
Если код нормальный — комментарии не нужны.
Если код говно — то комментарии не помогут, так как качество комментариев будет ниже качества кода.

А к чему вы здесь приписали документацию? Я ничего против неё не говорю. Может еще меня в педофилии обвините из-за того, что я не поддерживаю комментирование?
Вы делите все на черное и белое — в реальной жизни так не бывает. Не бывает экстремальных ситуаций, когда код идеален или до бесконечности ужасен. Комментарии — это неотъемлемая часть документации.

Есть такое понятие — «исторически сложилось». Меняются разработчики, меняется их число и квалификация, стандартны кодирования, контроль над кодом. Разные команды разработчиков по-разному относятся к своим проектам и с разной долей ответственности. Одни делают ревью, другие дебажат на боевых серверах.

> Если код нормальный — комментарии не нужны.
Код может быть нормальным и вполне качественным, но реализовывать сложную логику, которую сможет быстро объяснить доступный комментарий. Это более чем отличная практика читать код по названию функций и комментариям к ним, а также пользоваться генераторами документации на основе комментариев. Заставлять других разработчиков рыскать по коду в поисках значения входных параметров — это просто моветон.

>Может еще меня в педофилии обвините из-за того, что я не поддерживаю комментирование?
Я бы вас уволил.
я бы с вами не работал. если у вас такой код, что без комментариев в нём не разобраться — это издевательство над собой.
почитайте книжки умные. Фаулера, там. Он всё описал.
В любом коде можно разобраться, но на это может уйти разное количество времени. Обычно еще при планировании задач закладываются часы на документирование кода. Я читал достаточное количество умных книжек и имел честь общаться с большим числом высоко квалифицированных разработчиков, а также имею свой большой опыт разработки — только дилетанты, не имеющие опыта работы в команде и работы над крупными проектами, считают отсутствие комментариев нормой.
только дилетанты, не имеющие опыта работы в команде и работы над крупными проектами, считают отсутствие комментариев нормой.

ну да, Фаулер — дилетант, а вы — д'Артаньян.
Ответ на мой комментарий с вашей стороны до нельзя банален и очевиден. Нет ничего проще, чем сослаться на книжку, из которой вы выудили не то, что нужно. Перестаньте бить себя в грудь доказывая откровенную чушь. Делетантами я назвал тех — кого назвал, не передергивайте. Я не считаю себя д'Артаньяном, так как всегда стараюсь расширять свой кругозор, ищу существующие решения и консультируюсь с людьми, которые разбираются в вопросе на моем уровне или имеют больше знаний и опыта. Моя совесть в этом вопросе чиста.

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

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

если хочется поставить комментарий — можно 5 минут потратить на переписывание кода и комментарий уже не понадобится.
вон выше был пример комментария. "// Magic. Do not touch.". Помогло? 10 минут и комментарий уже не нужен.
На самом деле, принцип «работает — не трогай», часто спасает от траты времени и помогает не отвлекаться на все подряд. Если не работает или требуется использовать где-то еще данный участок кода — другой разговор, стоит потратить время и зарефакторить.
принцип «работает» — не трогай — это основной источник кучи непонятных и трудноуловимых багов. особенно в языках с динамической типизацией
Согласен, но стоит трогать опять же, только при необходимости, иначе при огромных объемах кода, можно только и делать что рефакторить. Пожалуйста, учитывайте, что этим невозможно заниматься 100% времени, так как на разработчика в первую очередь сваливается «текучка» и новый функционал + поддержка работоспособности старого.
ну, на самом деле, согласен. идеальный код быть не может. но в приемлимом состоянии его всё-таки придерживать стоит. чтобы не было всяких «это магия».
Рассмотрим реальный пример. Встречаете вы функцию, которая осуществляет фильтрацию данных на 200 строк. Объем кажется большим? Меньше ее врядли сделать — она формирует оптимальный и быстрый sql-запрос. На входе у нее массив, который должен содержать значения фильтров. Решение понятно — один входной параметр позволяет легко добавить/удалить фильтры. Почему входящие фильтры не сделаны через объекты? Потому что объем стал бы 1000 строк. Дополнительное условие — задача была горящая и требовала достаточно быстрой реализации. В итоге мы получаем в данной ситуации хорошую работающую функцию, но разработчик не указал в комментарии, какие входные параметры она принимает.

В итоге, каждый кто захочет использовать ее, должен будет читать все двести строк, чтобы понять в каком формате приходят входные данные и что они значат.
это отличный пример того, что комментарии нужны тогда, когда проблемы с кодом. у вас в одном месте и фильтрация данных и генерация запроса, еще и хрен знает сколько всего в те 200 строк напихано. тут с комментариями или без чёрт ногу сломит
Речь не идет о проблемах с кодом. Речь о том, что с комментарием отпала бы необходимость читать код этой функции и сетовать на данную реализацию, какой бы она не была. В проекте может быть тысячи функций, вы предлагаете читать каждую?
Вы знаете, комментарии еще очень важны в рамках специфики определенных проектов. Ведь программисты не занимаются тупым кодированием в сферическом вакууме, их код отражает вещи, происходящие в реальном мире. Задача комментариев — помочь разобраться, почему эта функция работает именно так, а не иначе, как могло бы казаться. Комментарии помогают понять предметную область, с которой работает система.
почему эта функция работает именно так, а не иначе, как могло бы казаться

Плохие программисты у вас.
Пока что плохим программистом представляетесь лишь Вы. А у нас сложная и многогранная предметная область, сотня серверов, несколько миллионов строк кода, более сотни проектов и очень высокие нагрузки.
и при этом ваши программисты не могут написать такие функции, чтобы они работали как ожидается?
Вы неверно поняли суть того, что я сказал.
Ситуация — приходит новый программист, который раньше никогда не вникал, как устроено, например, расписание сеансов кинотеатров и что текущий день заканчивается не в 24 часа, а в 6 часов утра следующего дня и функция, которая делает выборку, сделает не то, что нужно, если не будет делать временной сдвиг, принимая на вход период с 9:00 по 0:30, вернув промежуток за 8,5 часов, а не за 15,5. Мысль ясна?
такие комментарии я отнесу к разряду «исключение».
на самом деле бывают места, где необходимы комментарии, я об этом говорил. например, неочевидный код, может быть следствием оптимизации, или при использовании сторонней библиотеки приходится применять какой-то хак из-за её бага. но это всё — исключительные ситуации, которые в практике нечасто.
К сожалению, часто приходится применять методологию разработки «KDD», от слова «костыль» :) Все проистекает из того, что, к примеру менеджерам проекта кровь из носа требуется добавить функциональность, реализация которой «по-правильному» займет неделю, а клиент требует от них этого как всегда «вчера». Но самая засада, что менеджер имел в виду не то, что вы с ним утвердили. Это выясняется через неделю, и один костыль заменяется на другой с минимальными затратами… :D С идеалогической точки зрения это кажется злом, но это реалии. Посмотрите вот это видео, как раз в тему: vimeo.com/10922497
Очень интересно. А можно деталей чуть чуть? Можно в личку если не хотите тут.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории