Не судите чужой код строго

    Так сложилось что большую часть своей сознательной жизни я программирую на PHP. Наш мозг, воспринимая информацию из любого источника, делает это без отрыва от авторитетности этого источника. Грубо говоря, если вы любите PHP — вы автоматически добавили очков авторитетности автору этой статьи, а если не любите — автоматически отняли. Этот процесс происходит на бессознательном уровне и является по сути призмой восприятия, которая с одной стороны защищает нас от падения в бесконечный анализ информации любой степени авторитетности, но с другой стороны ограничивает нас в поиске новой более актуальной информации. Самое поганое здесь то, что авторитетность источника редко когда проверяется на сознательном уровне (потому что на это нужны время и ресурсы в виде драгоценных калорий), я могу быть с той же долей вероятности разработчиком плюсов, домохозяйкой-кухаркой, водопроводчиком без принцессы или генетически модифицированным котом. Не судите мою статью строго, у меня лапки.

    То же самое относится к чтению чужого кода: если его автор сидит по левую руку от вашего трона, работает в вашей фирме 10+ лет и зарабатывает на один ноль больше вас, это совершенно не то же самое, что автор, которого уволили за что-то плохое, а вас наняли на его место. Но по сути то и там и там код — это всего лишь набор байтов, которые было бы полезно оценивать без привязки к авторитетности источника.

    Когда мы читаем чужой код, нас могут посещать самые разнообразные эмоции: восхищение, смех, раздражение, разочарование, полное неприятие. Полезно знать о том что проявление любых эмоций в любом контексте — это автоматический ответ низшего (первого) уровня нервной системы, сформированный эволюционным путем, необходимый в первобытной среде. Основная задача такого ответа, в случае «негативной» эмоции — запустить механизм действий «бей или беги» с одной единственной целью — выжить. В нашей текущей офисной среде при анализе чужого кода подобный ответ становится скорее бесполезным и даже вредным, поскольку вы тратите на него драгоценное время и ресурсы, плюс загрязняете свой мозг нейромедиаторами, понижающими вашу сообразительность в угоду скорости реакции. Хорошая новость в том что этот ответ можно перепрограммировать. Можно подавлять негативные эмоциональные реакции, а можно их инвентировать, например, смеяться там где вы раньше злились. Смех, в отличие от злости, выбрасывает в мозг хорошие вкусные полезные нейромедиаторы, доставляющие удовольствие, закрепляющие опыт и мотивирующие на дальнейшую работу.

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

    Современные средства разработки позволяют практически на лету преобразовывать чужой код в более понятные и приятные структуры. Функция или переменная плохо названа — ctrl+shift+R и в пару секунд она называется по хорошему. Табуляции вместо пробелов, неудобно, непривычно раскиданы отступы и открывающиеся бракеты в египетском стиле — ctrl+shift+F и форматирование восстановлено! Комментарий избыточен или устарел — ctrl+D и его нет. Если изменить призму восприятия, чтение чужого кода может превратиться в увлекательную интерактивную детективную игру.

    Код это всего лишь инструмент. Как бы плохо и ужасно он не был написан, в конкретное время и в конкретном месте он успешно решал конкретную проблему, а значит он уже «оправдан». Что-то изменилось в бизнес-требованиях, что то было не учтено — код поломался или стал не актуален, и это нормально. Код имеет свойство эволюционировать самыми разными путями: и постепенно, обрастая пластами и революционно, переписываясь с нуля. Конечно хорошо, когда программист предвидит будущее и на начальных этапах закладывает в код возможности для дальнейшего его развития. Но эта секира остра с двух сторон, вы можете ошибиться с предсказыванием будущего, будущее может не наступить вовсе, а время и ресурсы будут безвозвратно утеряны. Тут важно понимать код какой степени качества от вас требуется. Если это огромная распределенная система, модули к которой программируют ваши коллеги из самых разных точек земного шара в фирмах слабо связанных с вашей, тогда да, имеет смысл использовать модные паттерны, оборачивать модули в сервис-контейнеры даже там где вы не можете себе представить зачем это нужно. Но если это маленькая локальная CRM для одной фирмы, модули которой зависят друг от друга настолько жестко, что отключение любого модуля по сути ведет к остановке работы всей системы… в этом случае вполне оправданно вызывать чужие методы напрямую, это уменьшит количество классов, облегчит вашу оперативную память и сократит время на отладку проблем. Но вот возникает ситуация когда маленькая локальная CRM превращается в нечто расширяемое, что ваша фирма хочет выложить в открытый доступ и продавать. Бизнес-требования изменились. Стоит ли винить программиста в том что он не предвидел этого?

    Стандартизация


    Код это всего лишь инструмент, но его создание — это чистое творчество. Любую задачу можно решить бесконечным числом самых разнообразных способов. Некоторые из них более производительны, чем другие — пример объективной оценки. Некоторые из них более читабельны, чем другие — пример субъективной оценки. Даже если вы убедите весь офис в том что какой-то кусок кода не читабелен, все еще останется как минимум один автор, который с вами не согласится. Стандартизация кода направлена на то чтобы преобразовать чистое творчество в как можно более рутинный набор действий для того чтобы другим программистам было проще разбираться в вашем коде. То есть, по сути, чтобы вас можно было заменить другим специалистом, более покладистым и дешевым. А через пару десятков лет так и вовсе искусственным интеллектом. Стоит помнить, что если какой-то стандарт противоречит здравому смыслу, возможно его имеет смысл нарушать в некоторых местах, а то и вовсе отказаться от него или заменить на другой, более подходящий.

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

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

    Аналогичные примеры встречаются сплошь и рядом и в культуре программирования. Стандарт PSR ратует за 4 пробела вместо табуляции, игнорируя очевидный факт: среда разработки большинства PHP-программистов изменилась с консольных редакторов на полноценные IDE, в которых оперировать табуляциями удобнее во многих смыслах: и удалять проще, нажимая Backspace один раз, и настроить можно индивидуальную длину табуляции по вкусу.

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

    Лично я при разработке своих проектов использую:

    • CamelCase для именования классов и методов
    • $CamelCase для именования переменных, содержащих экземпляр объекта
    • $snake_case для именования переменных, содержащих простые типы

    У меня нет никаких проблем отличить имя класса от имени метода, поскольку первое — существительное, а второе — глагол. К тому же подсветка выручает. Но это мой личный вкус, я его никому не навязываю. Это персональная призма восприятия, она индивидуальна для каждой отдельной головы. Кому то «повезло» сразу вляпаться в популярный стандарт, кому то «не повезло» начать свою карьеру с альтернативных, а кто-то вообще разрабатывал собственные. Я вас веду к тому, что вместо того чтобы переучивать других, возможно, имеет смысл переучить себя воспринимать код в любых стандартах. Или даже вне стандартов.
    Конечно, адепты стандартизирования в этом месте возмутятся и накидают мне множество причин против. Эта статья не для них, я пишу ее для тех, кому интересно проникать в суть вещей, пытаться представить что на самом деле имел в виду автор и какую цель преследовал.

    Умение разбираться в чужом коде


    Триггер, вызывающий рвотные порывы у подавляющего большинства программистов (пример субъективной оценки). Вам никогда не казалось странным, что зачастую нам проще переписать весь код с нуля, чем разбираться в чужом? В любой другой отрасли мы действуем иначе: сперва учимся читать, потом — писать; сперва пользоваться (электроприборами, зданиями), затем — их проектировать. Мне кажется все дело в нашем образовании (конкретно в области программирования). Нас учат достигать цели самым прямым и быстрым способом, используя некоторые свеже-приобретенные знания. В результате мы комбинируем их (знания) ровно до тех пор пока «оно» не заработает, немного тестируем и отправляем учителю на модерацию. На мой взгляд было бы неплохо добавить в этот процесс дополнительную ступень, на которой мы сравниваем наш код с мастер-кодом, который хоть и не является идеальным и единственно правильным, но дает альтернативный путь решения, зачастую более оптимальный и читабельный.

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

    Заключенька


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

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

      +5
      >Но по сути то и там и там код — это всего лишь набор байтов, которые было бы полезно оценивать без привязки к авторитетности источника.
      Так себе идея.

      Слегка условный, но типичный пример — читаем из внешнего источника строку, и пытаемся преобразовать ее в число. Как назвать отстутствие проверки и/или обработки ошибки в этом случае? Бизнес-требования изменились? Да как бы не так — это внешний источник, и доверять ему нельзя никогда.

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

        +1

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


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

          +1
          >дополнительно в отдельном потоке без привязки к авторитетности
          В общем-то я имел в виду, что полностью это развязывать не стоит — потому что характерные типы ошибок специфичны для человека. И кстати, опытные и матерые тоже имеют тенденцию к тому, чтобы делать типовые для себя ошибки. Просто другие.

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

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

              –1
              Даже опытный и матерый программист может допустить глупую ошибку в силу многих причин.

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

              Если программист под рассмотрением может допустить ошибку, то этой ошибкой вполне может быть пропуск комментария. Т.е. утверждать на 100% как оно должно было быть вы уже не можете.
            0
            Слегка условный, но типичный пример — читаем из внешнего источника строку, и пытаемся преобразовать ее в число
            Такое вполне может быть, если профилирование показало, что чтение с проверкой корректности снижает пропускную способность сервиса на пару гигабит в секунду, поэтому проверки сознательно убрали.
              +1
              Не верю (с) Станиславский. Если вам все равно нужно число — вы так или иначе проделали преобразование. Обработка ошибок (если как правило их нет) обычно не может так снижать пропускную способность.
                0
                Хорошие проверки, это не только валидация символов, но и проверки на переполнение, что числа вмещаются в текущие int32/int64. То есть, больше ветвлений.

                К тому же, код основного цикла обработки мог слегка распухнуть из-за десятков тщательных проверок и перестать влезать в L1 Instruction Cache.
                  +2
                  Я специально написал выше «обычно». Сервисы, которые из внешнего источника читают данные, и при этом требуют оптимизации такого уровня — они вообще-то достаточно редки. Если же речь такой случай — то опытные программисты обычно просто оставляют следы, позволяющие понять причины того или иного решения.
                    0

                    Вот да. Недостаточно писать работающий код, надо писать понятный код.

                0
                Там, скорее всего, тормозить будет файловая система или база данных, а не проверки.
                0

                Дайте определение внешнего источника.

                  0
                  Я вообще-то в первом же комментарии его дал — это источник, которому нельзя доверять. Чем оно не устраивает?
                +3
                Мне кажется, на вопрос в разделе «Умение разбираться в чужом коде», отвечает раздел «Стандартизация».

                Хотя на мой взгляд стандартизация — это просто перераспределение страданий. Чем более стандартизирован код, тем больше степень страданий при написании, и меньше при чтении.
                  +2

                  Оформление вообще не проблема, проблема это когда программист не стал утруждать себя чтением доков. Как может не раздражать, когда эндпойнт назван /api/user/createUser или все ответы, даже с ошибкой, имеют статус 200? Или когда код лежит архитектурно не в том месте? А зачем было открывать файл контроллера и писать там, если можно прямо в роутах оставить, ведь главное что работает и выполняет задачи бизнеса.

                    0

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

                      +1

                      У меня никакого раздражения, я, будучи спокоен, как удав, пишу комментарий и жму request changes.

                    +2
                    Как бы плохо и ужасно он не был написан, в конкретное время и в конкретном месте он успешно решал конкретную проблему

                    Да, например, проблему job security автора кода. Резко войду в положение и начну любить код (и его автора).


                    Некоторые из них более читабельны, чем другие — пример субъективной оценки.

                    Ставить открывающую { на той же строке или на следующей — субъективщина. Но когда читабельность кода инвариантна относительно вставки произвольного числа пробелов и новых строк на произвольных местах или же относительно произвольного переименования идентификаторов в случайные строки, то это уже начинает пахнуть объективностью. Можно энтропию там измерить, например. Или колмогоровскую сложность, не знаю.

                    • НЛО прилетело и опубликовало эту надпись здесь
                        0

                        Или если имена переменных уже имели вид вроде a, a2, b_bvrg или bOld_aux2.

                          0

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


                          int someName(const int* a, int count) 
                          {
                              int rv = 0;
                              const int* f = a;
                              if (f)
                              {
                                  const int* t = f + count;
                                  for(;f < t;) 
                                  {
                                      if (!*(f++)) 
                                          rv = 1, break;
                                  }
                              }
                              return rv;
                          }

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


                          bool hasZero(const int* arr, int count) {
                              if (arr == nullptr) 
                                  return false;
                          
                              for(int i = 0; i < count; ++i)
                                  if (arr[i] == 0)
                                      return true;
                          
                              return false;
                          }
                          • НЛО прилетело и опубликовало эту надпись здесь
                              0

                              (зануда mode on) Только зря вы переносите операторы в for и if на новую строку без фигурных скобок. Уже не первое поколение программистов наступает на грабли, дописывая там ещё оператор.

                          +1
                          Функция или переменная плохо названа — ctrl+shift+R и в пару секунд она называется по хорошему. Табуляции вместо пробелов,… — ctrl+shift+F…! Комментарий избыточен или устарел — ctrl+D и его нет.
                          О, отличные лайфхаки! А подскажите, с чем там надо Ctrl жать, когда есть файл на 6500 строк и там ряд функций, строк по 400 каждая, полученных путем копипасты друг из друга с небольшими изменениями, реализующими несколько различающуюся бизнес-так сказать-логику?
                          Где по 200 строк типа x= asd_ewdfgh(hgfd_trew_zxcvb(zyx::asdf_iuyt(qwe_rtyu.begin(), qwe_rtyu.end()) + ytre_qwe(zyx::asdf_iuyt(qwe_rtyu.begin(), qwe_rtyu.end()); с разными названиями переменных, но одинаковым смыслом, который можно вынести в функцию x= do_work(qwe_rtyu);.
                          По итогу файл ужимается до 300 строк (обычной длины) и чуть проще становится для понимания, но занимает это жуть как много времени, вот бы хоткей какой знать…
                            0

                            По своему опыту могу сказать что, например, Intellij прекрасно справляется с пониманием того что где-то есть такая же логика, но с другим названием переменной

                          • НЛО прилетело и опубликовало эту надпись здесь
                              0

                              А почему я должен испытывать какие-то эмоции? Это обычный контроль качества. Я спокойно описываю необходимые изменения, аргументирую, и тыкаю кнопочку request changes.


                              Если разработчик воспринимает сухую аргументированную критику кода как личное оскорбление — это его проблемы, не мои.

                                +1
                                Я обнаружил, что есть люди, которые на это обижаются. Их расстраивает что они вот старались-старались, писали код изо всех сил, а вы со своими сухими «здесь segfault при N=2», «не соответствует пункту 3.2 codestyle», «здесь race condition», «здесь поведение не соответствует указанному задаче», «это изменение приводит к проблеме, ранее исправленной в задаче JIRA-1234» заставляете их понять что их код плох. Дальше у них срабатывает логический переход «мой код плох -> я плох», ваши аргументы становятся аргументами в пользу этого, и они бегут жаловаться что вы такой-сякой бессердечный, жестокий и вообще токсичный.
                                  0

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

                                    0

                                    Не нанимать людей, которые еще не повзрослели (ментально, а не физически).


                                    Это еще на собеседовании сразу видно. Если не смогли разглядеть на собеседовании — на испытательном сроке точно проявится.

                                    0

                                    Пусть тогда и на компилятор обижаются, когда он warning-и выводит.


                                    Детский сад, штаны на лямках.


                                    Почему меня вообще должно волновать, старался человек или нет? Значение для бизнеса имеет только результат. Зарплату разработчик получает не за старания, а за выполненную с надлежащим качеством и в надлежащие сроки работу.


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

                                  +1
                                  Хабр не поощряет таких комментариев, но все же напишу просто. Молодец!
                                    –1
                                    Стандарт PSR ратует за 4 пробела вместо табуляции, игнорируя очевидный факт: среда разработки большинства PHP-программистов изменилась с консольных редакторов на полноценные IDE, в которых оперировать табуляциями удобнее во многих смыслах: и удалять проще, нажимая Backspace один раз, и настроить можно индивидуальную длину табуляции по вкусу.

                                    Во-первых, в любой нормальной IDE это прекрасно настраивается.


                                    Во-вторых, Developers Who Use Spaces Make More Money Than Those Who Use Tabs :)


                                    Ну и в-третьих:


                                    • внутри команды разработчиков/группы единомышленников может быть какой угодно кодстайл (но зачем, если есть PSR-12?);
                                    • один разработчик может использовать какой угодно кодстайл (но зачем, если есть PSR-12?);
                                    • всё, что выкладывается публично, должно быть отформатировано по PSR-12, иначе лучей ненависти будет слишком много.
                                      –1
                                      Затем, что удалять и добавлять один таб гораздо удобнее, чем 4 пробела. Про навигацию стрелками с пробелами я вообще промолчу.

                                      Ни одного разумного довода за пробелы я не слышал никогда.
                                        –1
                                        Во-первых, в любой нормальной IDE это прекрасно настраивается.

                                        Вы пропустили этот пункт?

                                          0
                                          Т.е. если есть костыль, то всё хорошо?
                                            0

                                            Какой костыль? Вы шторм открывали хоть раз?

                                              0
                                              Ок, перефразирую. Если IDE компенсирует недостаток какого-либо подхода, это не значит, что его нет.

                                              Хотелось бы всё-таки услышать хоть какие-то разумные аргументы за пробелы.
                                                0

                                                В любой нормальной IDE нет никакой разницы.


                                                Лично для меня нет вообще никакой разницы. Главное, чтобы в проекте был code style и все его придерживались. Какой именно — по барабану. Но если есть общепринятый стандарт, всегда выгоднее его придерживаться: если понадобится форкнуть какую-то стороннюю библиотеку, с вероятностью 99% она оформлена в соответствии с общепринятым стандартом, и не понадобится ее реформатить, что упростит последующие мерджи с апстримом.

                                                  0

                                                  Если понадобится одолжить чужую клавиатуру, то с вероятностью 99% это будет QWERTY :]

                                                    +1

                                                    Купить вам клавиатуру — это копейки, а регрессии из-за сложностей с мержем могут бизнесу обойтись в миллионы.


                                                    Если вы пишете опенсорс или свой собственный проект, то, конечно, дело ваше. А если вы получаете зарплату, то ее вам платят не за ваши личные хотелки, а за то, что нужно бизнесу. А стандартизация всегда бизнесу выгодна, любое нестандартное решение это всегда дополнительный cost of ownership. Любое нестандартное решение должно чем-то компенсировать этот рост TCO. Нестандартный code style не компенсирует это вообще никак, хоть убейся.


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

                                                  –1
                                                  Да пожалуйста, пробел везде = 1 символ на экране, табуляция — везде разная, где-то визуально она 4 пробела, где-то 8. Используя пробелы вы везде получите одинаковое отображение, хоть в IDE, хоть в блокноте, хоть в vim'е.
                                                  Тот же phpstorm штатно из коробки использует 4 пробела. При желании можно настроить на табы. Лень нажимать 4 раза бекспейс/delete? Есть Ctrl+Alt+L.
                                                    0
                                                    Я на самом деле поискал после этой дискуссии.

                                                    1. Некоторые редакторы вообще не способно нормально отображать табы.
                                                    2. При разных настройках отступов, съезжают блочные комментарии, сделанные табами (лол) справа от текста.
                                                    3. У кого-то код ревью с лимитом на длину строки не проходил из-за того, что у ревьюэра стояли более широкие табы.

                                                    Ну и Ctrl+Alt+L есть не везде, так что либо страдания в одну сторону, либо в другую.
                                                      +1
                                                      Данный шорткат именно для шторма указал. Проблем с табами по факту больше, чем профита, на мой взгляд.

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

                                      Самое читаемое