перечитываю "Верёвка достаточной длинны, чтобы выстрелить себе в ногу"
остановился на форматировании исходников.
поражает такая вещь: этой книжке туева хуча лет, её многие читали
и он далеко не единственный кто об этом пишет,
однако товарищи программисты по прежнему пренебрегают абсолютно всеми рекомендациями,
притом не только в коде, но и в тексте (пример
кстати, частенько этим страдают хорошие алгоритмисты
мне иногда кажется, что было бы неплохо некоторых бывших студентов сразу садить на сопровождение,
но перед тем как им выдавать код, форматировать его вот так:
Скрытый текст
Это быстро научит трём вещам:
1) тому, как писать не надо
2) форматирование облегчает чтение и понимание кода
3) (хорошие, актуальные) комментарии — весьма ценный стаф
*) в сумме это научите отличать хорошее от плохого и ценить хорошее
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Философ, Вы писали:
Ф>однако товарищи программисты по прежнему пренебрегают абсолютно всеми рекомендациями, Ф>притом не только в коде, но и в тексте (пример
Здравствуйте, Baudolino, Вы писали:
VD>>Что-то я не понял юмора. По ссылке одна строчка кода — атрибут. Что там можно отформатировать то? B>Там после него издевательство.
Что? Причем тут форматирование то?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Поэтому мы используем automatic coding style enforcement, когда билд ломается если код не соответствует принятому стандарту. Все остальные средства, как то вордовский документ с описанием стандарта, уговоры и проработки нарушителей на митингах, споры о правильный и неправильных стандартах — не эффективны.
Здравствуйте, Философ, Вы писали:
Ф>Почему? Ф>блин, неужели это так сложно, долбануть лишний раз энтер, или пробел после запятой?
Может, потому, что вопрос не в "долбануть энтер", а в эстетике текста? А представления о ней у всех разные.
Ф>кстати, частенько этим страдают хорошие алгоритмисты
Именно. Хороший алгоритмист видит красоту алгоритма, но ему нужна и красота текста кода.
Ф>мне иногда кажется, что было бы неплохо некоторых бывших студентов сразу садить на сопровождение, Ф>но перед тем как им выдавать код, форматировать его вот так:
Ваша реакция показывает, что Вы вместо поиска причин заняты решением задачи "как бы посильнее наступить на больную мозоль".
1. Пишу код без выделения структуры отступами и переносами:
int x=0;std::vector<int> y;
for(int i=0;i!=y.size();++i)if(y[i]>100)++x;std::cout<<x;
2. Рядом его же с отступами:
int x = 0;
std::vector<int> y;
for (int i = 0; i != y.size(); ++i)
if (y[i] > 100) ++x;
std::cout<<x;
— Всем понятно насколько важно форматирование?
2. Начинаю писать комментарии в коде, типа
int x = 0; // здесь будет количество книг дороже 100 рублей
std::vector<int> y; // y - это список со стоимостью книгfor (int i = 0; i != y.size(); ++i) // проходим по всему списку книгif (y[i] > 100) ++x; // если книга стоит больше 100 рублей увеличиваем счетчик
std::cout << x;
— Комментарии это хорошо?
— Да!
3. Переписываю код:
int CountBooksMoreExpensive(const BookList& books, int price)
{
int count = 0;
for (int i = 0; i != books.size(); ++i)
if (books[i] > price) ++count;
return count;
}
std::cout << CountBooksMoreExpensive(books, 100);
— А нужны ли комментарии, если код написан понятно?
Здравствуйте, Философ, Вы писали:
Ф>Это быстро научит трём вещам: Ф>1) тому, как писать не надо Ф>2) форматирование облегчает чтение и понимание кода Ф>3) (хорошие, актуальные) комментарии — весьма ценный стаф
Не, они решат, что именно так и надо писать.
Проблема, на самом деле, в отсутствии уважения к другим людям — тем бедолагам, которые будут этот код (или текст) читать. И решать ее, если это в принципе возможно, нужно через то место, через которое прививается уважение и прочие общечеловеческие ценности, а не через то, через которое прививаются технические навыки.
Здравствуйте, MTD, Вы писали:
MTD>Я студентов учил так:
MTD>1. Пишу код без выделения структуры отступами и переносами: MTD>2. Рядом его же с отступами: MTD>- Всем понятно насколько важно форматирование?
студентом никогда не был, а теперь уже и не буду, но малым сапом дорос до архитектора и хочу сказать, что первый код я читаю быстрее второго, т.к. банально меньше движений глазами. вам никогда не рассказывали как читал книги владимир ильич ленин? странно. должны были рассказывать. ваш код (второй пример) напоминает реферат студентов, набранный 12 кеглем с двойным междустрочным интервалом и стилем "новый абзац на новой странице". помилуйте, хорошего в меру.
если следовать вашим рекомендациям, то программа в 1,000 строк запросто превратится в программу в 10,000 строк. на хрена тянуть код по вертикали?! ааа... понимаю... потому что вы листинги распечатываете на принтере. а у нормальных людей широкоугольные монтиторы и главное -- вместить единицу смыслового блока на экран. что такое "единица смыслового блока" пояснять не буду, т.к. это зависит от, но общий смысл должен быть ясен.
MTD>2. Начинаю писать комментарии в коде, типа MTD>int x = 0; // здесь будет количество книг дороже 100 рублей MTD>std::vector<int> y; // y — это список со стоимостью книг MTD>- Комментарии это хорошо? MTD>- Да!
в индустрии студентов быстро научат сначала писать документацию к еще несуществующему коду на английском языке, а после всех утверждений и согласований воплощать ее в код. по сути документация и есть комментарий.
кстати, комментарий у вас не правильный. "кол-во <имя_сущности_1>, дороже <пороговый_уровень> <валюта>". но вообще, если абстрагироваться, то в комментах нужно написать, что считаем объекты, значение которых зашкалило. при повторном использовании кода такой комментарий не поставит в тупик если вы воткнете его в телеметрическую систему, считающую сколько раз в году температура падала ниже нуля по фаренгейту.
MTD>3. Переписываю код: MTD>int CountBooksMoreExpensive(const BookList& books, int price)
кошмар. немедленно учить английский. а вслед за английским -- программирование. извините, но это код на бейские. потому что только на бейсике повторное использование кода не предусматривалось в принципе (имеется ввиду ранний бейскик). повторяю еще раз -- данный код не имеет никакой "книжкой" специфики и может считать хоть огурцы, хоть пятна на солнце. в первородном виде (где у вас был x и y) никаких проблем не возникало. а после "перестройки" код стал неюзабельным.
при этом очень странно видеть int price. я, конечно, понимаю, что вы из россии, но это не оправдывает такого стиля. даже если предположить, что цена в копейках -- не факт, что при очередном витке инфляции она влезет в int. короче, ваш код взрывает моск. он неправильный, не реюзабельный и к тому же нечитабельный, и не писабельный. без автокомплита можно сдохнуть набирать такие длинные имена. сразу видно, что вы не программируете, а учите программированию, что есть две большие разницы.
CountBooksMoreExpensive -- это в какой разведшколе так учат? вам там не говорили, что есть такое понятие как threshold level ? а еще в более общем плане это даже не пороговый уровень, а соответствие критерию или критериям. код может меняться и обрастать новыми критериями, в которую входит не только цена, но еще и спец налог или таможня или историческая стоимость. а у вас имя функции жестко закодировано и эта функция уже вероятно попала в документацию и вызывается из 100500 мест. и теперь вы уже вынуждены писать комменты и объяснять, что в силу исторических причин имя не отражает сущности...
смотрите в корень. в корне что? в корне не цена. в корне вернуть кол-во элементов списка, отвечающих некотором критериям, причем эти критерии хардкодить может только идиот. причем хронический. нормальные люди задают критерии в виде текстовой строки (а в реальности для этих целей используются скрипты или языки запросов).
в реальности список книг будет в базе и в реальности ваш код сводится к запросу. короче, очень плохой пример вы привели...
а вот если вы пишите функцию, вычисляющую число пи, то снова попадаете на бабки. то есть на короткие имена переменных. потому что в любой математической статье, описывающие методы вычисления числа пи, приводятся формулы, излагаемые весьма лаконичным языком. если в программе у переменных те же имена, что в статье -- это сильно облегчает ее понимание.
у функции, вычисляющее значение пи, может и должно быть имя pi, потому что pi оно даже на северном полюсе pi, а не sin. а CountBooksMoreExpensive это пример того как не нужно называть функции. именно такие имена и порождают необходимость в постоянном рефракторинге.
кстати, еще одна шпилька. дебильные аргументы. список книг -- это абстрактный список. а цена это конкретный int. двойка вам и низачот. во-первых, у меня возникает вопрос -- почему цена не в списке книг? во-вторых, если цена не в списке книг, то все равно нужно передавать некую структуру, которую потом можно расширить.
MTD>- А нужны ли комментарии, если код написан понятно?
когда вижу такой код, то ищу мыло и веревку.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, мыщъх, Вы писали:
М>хочу сказать, что первый код я читаю быстрее второго, т.к. банально меньше движений глазами.
А понимаешь что он делает с какой скоростью?
Прочитать мало, надо ещё правильно его распарсить. А когда каша на экране то куда проще пропустить какую нибудь деталь.
М>главное -- вместить единицу смыслового блока на экран.
Чего? Тебе за единицы блоков которые влазят на экран платят что ли? inverse-индусский код?
М> что такое "единица смыслового блока" пояснять не буду, т.к. это зависит от, но общий смысл должен быть ясен.
В данном случае это называется каша.
MTD>>- А нужны ли комментарии, если код написан понятно? М>когда вижу такой код, то ищу мыло и веревку.
Найди уже скорее. Внеси свой вклад в улучшение метрики среднего качества кода.
Здравствуйте, Трололоша, Вы писали:
Т>Здравствуйте, мыщъх, Вы писали:
М>>хочу сказать, что первый код я читаю быстрее второго, т.к. банально меньше движений глазами. Т>А понимаешь что он делает с какой скоростью?
понимаю, конечно. пускай не в терминах книжных цен, но в этом месте как раз ни цен, ни книг и быть не должно, т.к. идет подсчет элементов по критерию. каких именно элементов -- зависит от контекста.
Т> Прочитать мало, надо ещё правильно его распарсить. Т> А когда каша на экране то куда проще пропустить какую нибудь деталь.
там нечего пропускать. код читается влет. а вот пример кода, который читается только со второго повтора:
и писал его выдающийся человек у которого есть чему поучиться. в том числе и тому, что в реальности приходится сталкиваться и с таким кодом, который шаблонным назвать трудно (хотя и к экзотике его не отнесешь).
поскольку, мы живем в мире людей и идей, то каждый день сталкиваемся с разными "культурами" и навыки скорочтения кода очень полезны. а с такими навыками приведенный пример читается буквально за секунду. пока глаза считывают следующую строчку -- мозг анализирует предыдущую.
М>>главное -- вместить единицу смыслового блока на экран. Т>Чего? Тебе за единицы блоков которые влазят на экран платят что ли? inverse-индусский код?
мне платят фиксированную зарплату вообще-то.
М>> что такое "единица смыслового блока" пояснять не буду, т.к. это зависит от, но общий смысл должен быть ясен. Т>В данном случае это называется каша.
это не каша. "единица смыслового блока" это то, что воспринимается целостно и pageup/pagedown утомляют, особенно когда это ssh на маковкской клаве.
americans fought a war for a freedom. another one to end slavery. so, what do some of them choose to do with their freedom? become slaves.
Здравствуйте, мыщъх, Вы писали:
М>первый код я читаю быстрее второго, т.к. банально меньше движений глазами. вам никогда не рассказывали как читал книги владимир ильич ленин?
Я готов вам поверить, что вы талантлив как Ленин, но на одного Ленина 1 000 000 (кстати так лучше, чем 1000000?) не столь одаренных, в числе которых и я, так что для меня первый код — непонятная каша.
М>если следовать вашим рекомендациям, то программа в 1,000 строк запросто превратится в программу в 10,000 строк. на хрена тянуть код по вертикали?!
Чтобы мог прочесть и понять обычный человек.
М>в индустрии студентов быстро научат сначала писать документацию к еще несуществующему коду на английском языке, а после всех утверждений и согласований воплощать ее в код. по сути документация и есть комментарий.
Описание интерфейса != комментарии в коде
М>кстати, комментарий у вас не правильный. "кол-во <имя_сущности_1>, дороже <пороговый_уровень> <валюта>". но вообще, если абстрагироваться, то в комментах нужно написать, что считаем объекты, значение которых зашкалило. при повторном использовании кода такой комментарий не поставит в тупик если вы воткнете его в телеметрическую систему, считающую сколько раз в году температура падала ниже нуля по фаренгейту.
Уммм, копипаст — нравится (интонацией Бората)!
MTD>>3. Переписываю код: MTD>>int CountBooksMoreExpensive(const BookList& books, int price) М>кошмар. немедленно учить английский. а вслед за английским -- программирование. извините, но это код на бейские. .........................
Чисто для справки — код:
1. Для студентов
2. Студентов русскоязычных
Пассажи, про treshold level и обобщение кода вообще порадовали, вы в школьных задачах, не спрашивали зачем человек вышел из точки А в точку Б? Еще вот похожий подход
Это злоупотребление структурой цикла for в C-подобных языках — цикл while, втиснутый в заголовок цикла for.
Такое написание нарушает последовательное чтение кода.
В комменте s лишняя. На ночь писать не надо было.
M>И потеряли описание функции. Теперь из кода не видно что он делает , и надо хорошо вчитываться
Во-первых, название функции, может быть? Во-вторых, давайте на каждый чих по функции будем заводить. Где надо и не надо. Ради названия. Вы тоже студентов учите, или как?
Ф>Это злоупотребление структурой цикла for в C-подобных языках — цикл while, втиснутый в заголовок цикла for. Ф>Такое написание нарушает последовательное чтение кода.
Не согласен. С одного взгляда на заголовок цикла я вижу, что цикл перебирает некие debugger event’ы, и верю, что он делает это правильно (даже не заглядывая в мануал на GetDebuggerEvent). Я также могу быть уверен, что добавление внутрь тела цикла оператора continue не сломает логику перебора (как будет в варианте с while).
С другой стороны, мне не нравятся чай-один и чай-два, при попадании r_eip между которыми цикл завершается. И ещё я, вероятно, предпочёл бы, чтобы code и r_eip были локальными переменными, а r_eip ещё и константой. И вообще логика попадания в интервал, да и сам интервал адресов — хорошие кандидаты в сущности предметной области.
for (long code = GetDebuggerEvent(WFNE_ANY|WFNE_CONT, -1)
code > 0;
code = GetDebuggerEvent(WFNE_ANY, -1))
{
if (breakpoint_range.contains(GetEventEa())
break;
}
Здравствуйте, SV., Вы писали:
SV.>Во-первых, название функции, может быть? Во-вторых, давайте на каждый чих по функции будем заводить.
хорошая привычка. SV.> Где надо и не надо.
где надо SV.>Ради названия.
и ради названия тоже, это способ повышения читабельности. SV.> Вы тоже студентов учите, или как?
нет
Здравствуйте, Centaur, Вы писали:
C>Я также могу быть уверен, что добавление внутрь тела цикла оператора continue не сломает логику перебора (как будет в варианте с while).
continue в этом цикле (да и вообще, в таких циклах) не к месту — цикл здесь служит конкретной цели.
C>С другой стороны, мне не нравятся чай-один и чай-два
+1
C>И ещё я, вероятно, предпочёл бы, чтобы code и r_eip были локальными переменными,
+1
C> а r_eip ещё и константой.
??
C> да и сам интервал адресов — хорошие кандидаты в сущности предметной области. C> breakpoint_range.contains()
На это я тоже обратил внимание, но я не знаю возможностей этого скриптового языка, поэтому не стал это предлагать.
Всё сказанное выше — личное мнение, если не указано обратное.