Есть ли способ отличить информативные комментарии от закомментированного кода?

38

В процессе программирования вы получите несколько комментариев, объясняющих код, и некоторые комментарии, которые удаляют код:

// A concise description 
const a = Boolean(obj);
//b = false;

Есть ли хороший метод для быстрого анализа, который какой?

Я играл с использованием 3 /-х и /** */для описательных комментариев.

Я также использовал плагин VSCode, чтобы выделить //TODO:и//FIXME:

туз
источник
2
Как примечание, так ///и /** ... */комментарии также используются некоторыми генераторами документации, такими как Doxygen или JSDoc. Если вы используете их или подобные инструменты, вы не сможете использовать такие комментарии для описательных комментариев, которые не предназначены для использования в документации.
Джастин Тайм 2 Восстановите Монику
1
В JavaScript большинство строк кода, вероятно, будут заканчиваться точкой с запятой. Если ваши комментарии не относятся к этому, это кажется довольно простым, и вы можете написать скрипт, чтобы легко это проверить;
Артемида поддерживает Монику

Ответы:

189

Существует очень простое решение: удалить закомментированный код.

На самом деле, есть только две веские причины закомментировать код: проверить что-то / исправить, или сохранить код, который вы могли бы использовать позже. Если вы что-то тестируете или исправляете, удалите закомментированный код, как только закончите с тестом или исправлением. Если вы сохраняете код, который можете использовать позже, сделайте его первоклассным кодом и поместите его где-нибудь, например, в библиотеку, где его можно будет использовать с пользой.

Роберт Харви
источник
108
Кроме того, если код был проверен: просто удалите его. Если вам это когда-нибудь понадобится, контроль над исходными
текстами поможет
38
Когда код удален, никто не замечает его существования. Это затрудняет восстановление. Оставлять закомментированный код имеет смысл, особенно если есть вероятность, что он будет использоваться в будущем.
USR
76
@usr: Когда код удален, никто не замечает, что он когда-либо существовал - и, по моему опыту, в 99% случаев, связанных с реальным миром, это правильно. В 1% могут быть некоторые значения в закомментированных строках, однако, если закомментированный код остается в течение нескольких недель или месяцев (или дольше), высоки шансы, что он даже не будет компилироваться из-за рефакторинга активного строки кода. Аргумент «потенциальная ценность для использования в будущем» часто используется как неправильное оправдание для людей, у которых есть эмоциональная проблема - убрать вещи из кодовой базы, для которой они потратили несколько часов умственного труда.
Док Браун
21
Я никогда не комментирую закомментированный код без дополнительных пояснительных комментариев. В редких случаях вы можете захотеть вернуть код в ближайшем будущем, но каждая из них является исключительной и требует объяснения для будущих разработчиков (или будущих вас). 90% моих комментариев: «Удалено, потому что кажется, что оно не используется. Удалите после ноября 2021 года, если проблем нет»
Джеймс Бенингер,
31
Мой коллега однажды сказал: «Здесь был код, который сделал X, но я удалил его», когда мы удалили какую-то функцию. Это сработало очень хорошо; Вы знали, что это было в исходной истории для этого файла, но это не беспокоило вас.
Эрик
45

В дополнение к превосходному ответу @ RobertHarvey, я считаю, что есть только одна законная причина, по которой я когда-либо сталкивался с возможностью сохранения закомментированного кода в систему контроля версий , даже временно: в случае неочевидного кода замены, который не должен или не может быть использован по какой-то причине прямо сейчас. , Даже тогда большая часть комментария должна быть объяснением, а не кодом замены. Это может быть ошибка или особенность языка, который еще не считается стабильным. Это может выглядеть примерно так:

# TODO: Replace with `foo = frobnicate(bar)` once <link.to/bug> is fixed
foo = [some complex workaround]

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

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

l0b0
источник
2
Обратной стороной этого является то, что иногда вам нужно объяснить, почему вы не используете его frobnicate(bar), чтобы никто не пришел и не попытался «исправить» ваш «не элегантный» код. Таким образом, вы показываете им, что знаете, что в идеальном мире эта frobnicateфункция была бы подходящим вариантом, но вы знаете из мучительного опыта, что она работает неправильно. Не может быть никаких ожиданий, что третья сторона даже считает это ошибкой, тем более что ее стоит исправлять; Вам все еще нужно оставить комментарий будущим программистам (включая себя) о том, почему вы не выбрали очевидный подход.
Монти Хардер
3
Связанная ситуация заключается в том, что может быть два способа сделать что-то, один из которых будет обрабатывать достоверные данные намного быстрее, чем другой, и один из них предложит более полезную диагностику, если по какой-либо причине он получит недопустимые данные. Если программа является частью процесса, который должен передавать только те данные, которые «гарантированно» действительны, но что-то в процессе не работает должным образом, наличие версии, которая медленнее, но предлагает лучшую диагностику, может сделать это гораздо проще определить, что идет не так.
суперкат
20

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

Однако, если вы ищете соглашение о маркировке кода для последующего удаления, мой старый фаворит:

//b = false; //TODO: remove

Некоторые //TODO:комментарии IDE или могут быть научены. Если нет, то обычно это строка для поиска. Лучше всего следовать соглашению, которое установил ваш магазин, потому что это можно сделать несколькими способами. Каждая база кода должна делать это одним способом. Поддерживает поиск

разбор быстро какой есть какой?

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

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

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

candied_orange
источник
Вместо того, чтобы видеть, скомпилированы ли комментарии, чтобы пометить их как код, вы можете запустить комментарии через процессор естественного языка и пометить те, которые анализируются как предложение или существительная фраза на языке, на котором говорит ваша команда.
TheHansinator
3
@TheHansinator, это звучит хорошо, но мой опыт работы с моими телефонами автоматически корректирует отношения с моим жаргоном кодера, заставляет меня быть осторожным.
Candied_Orange
Я предполагаю, что NLP, используемый для анализа комментариев кода, будет намного лучше, чем NLP, который обеспечивает автозамену, просто потому, что у компьютера есть целое предложение для работы и он не пытается исправить орфографические ошибки. Не говоря уже о том, что здесь также лучше использовать ложный минус - если человек может просмотреть комментарий перед удалением, он может просто переписать комментарий, в отличие от того, чтобы его не предупредили о бесполезной болтовне.
TheHansinator
3
при разборе: double buffer (flip on)-> C прототип или ультратонкий английский? не может сказать без контекста, не правильная целая конструкция ни на одном языке. Некоторые ложные срабатывания и отрицания неизбежны, когда комментарии по своей природе не ограничивают форму их содержания в любом направлении.
Леушенко
8

Я использую директивы препроцессора для удаления кода, а не комментарии:

//comment
active_code();
#if FALSE
inactive_code();
#endif

Это делает поиск очень простым, и моя подсветка синтаксиса воспринимает это как комментарий. Я даже могу свернуть это в одну строку:#if FALSE(...)

Вы можете расширить эту идею, чтобы иметь несколько вариантов:

#if OPTION == 0
code_for_option_0();
#elif OPTION == 1
code_for_option_1();
#else
code_for_all_other_options();
#endif

И проверка ошибок во время компиляции:

#if FOO >= 5
#error FOO should be less than 5!
#endif

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


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

AaronD
источник
Для чего в мире это будет хорошо? Вам нужно скомпилировать несколько версий?
твде1
@ Tvde1 Это одна из возможностей и потенциальный кошмар, если вы не очень хорошо справитесь . Но альтернатива, возможно, еще хуже. Если у вас есть несколько копий почти одного и того же кода, по одной для каждой вариации на общую тему, то вы должны поддерживать их отдельно и синхронизировать.
AaronD
Есть несколько способов сделать это, но все они имеют некоторую вариацию либо сложной проблемы конфигурации, либо проблемы независимого копирования: Вы уверены, что исправление достигло всех независимых копий? Что, если нет, и добавляется другая функция, которая затем ломается из-за ошибки, известной до этой функции, но не перенесенной до сих пор?
AaronD
3
Это работает только если у вас есть предварительные обработки шага , как С. Речь идет о javascript. Вы могли бы выполнить некоторую предварительную обработку, но это расширит возможности системы сборки, а также будет нестандартным. Если у вас нет системы сборки или система сборки вообще не поддерживает синтаксический анализ и выполнение кода, вы не сможете реализовать это решение. Наконец, он даже не решает вопрос - закомментированный код не является строго эквивалентным условно активированному коду. Это может быть остаток, который не должен быть включен.
ВЛАЗ
Условная активация - это только продолжение ответа, а не сам ответ. В противном случае я бы отредактировал его, чтобы включить комментарии, которые расширяют его еще больше.
AaronD
4

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

(Моя основа - C #, но это может быть применено к любому языку C-синтаксиса, например Java)

// An explanatory comment has a space between the comment marker and the content.

// The following lines are commented out code so do not have the space (except where indented).
//var a = something();
//if(a==2) {
//   doSomethingElse();
//}
IanF1
источник
2
Это полностью зависит от стиля: когда я закомментирую код, я обычно добавляю //к первому столбцу, и, поскольку практически весь код имеет отступ, в результате фактически всегда комментарий начинается с некоторых вкладок. Нормальные комментарии не получают от меня пробела, если рядом нет других комментариев с пробелом. Таким образом, ваш метод ужасно потерпит неудачу в комментариях, которые я произвел, и любой метод, предназначенный для распознавания моих шаблонов комментариев, будет ужасно неудачным для вашего.
начальник
@cmaster Ах, я понимаю, я думаю, что неправильно понял вопрос. Я предоставил простой способ форматирования комментариев таким образом, чтобы их можно было легко проанализировать по типу, а это не то, о чем просили.
IanF1
2

Я все еще интерпретирую вопрос, думая, что вы хотите найти закомментированный код.

Код в стиле C обязательно должен содержать точки с запятой, в то время как комментарий вряд ли содержит точки с запятой. Так что для закомментированного однострочного кода вы можете использовать это регулярное выражение:

\s*\/\/[\s\S]*;

Для многострочного закомментированного кода это может быть

\/\*[^\;]*;[^\;]*\*\/

Примечание. Visual Studio немного отличается от разрывов строк в регулярных выражениях, они не считаются пробелами, вам нужно указать явное \ n.

Мартин Маат
источник
2

Если вы используете редактор с работающим в фоновом режиме компилятором (например, Xcode и Clang), вы можете просто попытаться скомпилировать текст комментария. Например, «краткое описание» дает ошибки, «b = false;» - нет. Затем вы можете использовать другую подсветку синтаксиса.

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

gnasher729
источник
1

В других ответах были варианты «не комментируйте код». Но иногда вы все еще хотите это для справки.

Если вам действительно нужен код, чтобы остаться рядом, лучшим решением будет окружить код "#if 0 ... #endif", в идеале с комментарием, чтобы сказать, почему. Это рекомендуемая стратегия из различных стандартов кодирования, включая MISRA.

Грэхем
источник
-3

Просто, по крайней мере для меня - и в C / C ++. Комментарии в / * * / носят информативный характер. Тестовый код, который временно удален, закомментирован с ведущим //.

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

jamesqf
источник
Там также #ifdef __DEBUG ... #endif, или любое другое пользовательское определение, которое вы хотите использовать. __DEBUGЭто хорошо, потому что вам часто нужно только изменить конфигурацию проекта, чтобы получить его. Но большинство IDE позволяют вам также определять свои собственные конфигурации, которые могут дать вам все что угодно.
AaronD
Что вы подразумеваете под «тестовым кодом»? Модульные тесты? Они не должны быть закомментированы вообще, но должны храниться в наборе тестов и выполняться как можно чаще, независимо от того, считает ли кто-то это необходимым. Конечно, легко перекомментировать часть кода, но еще проще не делать ничего вообще, и тестовый набор уже
готов к работе
1
Argh, не делай этого. Комментирование кода «для проверки чего-либо» будет прекрасно работать в 99 случаях из 100 ... и в одном случае вы забудете удалить его (если он больше не нужен) или, что еще хуже, забудете его раскомментировать ( если это необходимо) и все может стать безобразным.
CharonX
@leftaroundabout: Нет, я имею в виду такие вещи, как операторы printf для проверки значений.
jamesqf
@jamesqf вам никогда не нужны такие вещи, для этого и нужен отладчик. Но даже если вы используете printf/ coutили подобное для правильного создания вновь написанного кода (что, я признаю, я делал сам в прошлом), на самом деле не очень эффективно оставлять их там. Если кто-то хочет внести изменения и знает, о каких переменных ему нужна информация, быстро и легко написать printfs заново, тогда как, если этот разработчик не знает, что нужно, и просто не комментирует все эти printfутверждения, тогда огромный объем текста в Терминал, скорее всего, им тоже не поможет.
оставлено около