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

Комментарии 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), такие сеттеры геттеры вообще бы не надо было писать. И соответственно, комментов бы к ним не было :)
Меня всегда возмущал код, где написан этот гет/сет мусор генеренный IDE, да еще и спокойно отдающий ссылки на mutable-объекты. Инкапсуляция нах! Я обычно сношу нах этот мусор вместе с тривиальными коментариями и делаю public поля.
Ваше право, конечно (если начальника это устраивает), однако, когда Вам вдруг потребуется что-то изменить, обращения придётся исправлять по всему проекту.
Сам я всё пишу руками и часто в одну строку, но у меня C++, а не java.
Ну тут специфика жавы — умная IDE и так все нормально переименует. А для C++ наверное акцессоры нужны.
Для 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
Очень интересно. А можно деталей чуть чуть? Можно в личку если не хотите тут.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории