Где-то в ноябре я решил побыть настоящим свободным художником и поработать в шезлонге у бассейна. Но судьба быстро дала понять, что всю жизнь мне суждено быть офисным или максимум домашним работником. Пацану лет 3 было скучно и он окатил мой ноут с водяного пистолета. Я успел посидеть там минуты две) Тогда с ноутом ничего не произошло, но на днях моник просто погас и все.
Отнес на ремонт - поменяют материнку, займет две недели. Там остались незапушенными 3 коммита. И я 2 дня вспоминал что в них было. Вспомнил. Восстанавливаю.
Мораль - пушьте свою работу в гит. Он в том числе и для этого создан.
Просто предупреждаю о том, что сегодня 1 апреля. А то народ уже забеспокоился, что Тейлор меня засудит и бросился спрашивать что со мной будет теперь)
Читать полностью…Пишу на Котлине и радуюсь null-safety. Везде он прикроет, не даст получить NullPointerException и все прекрасно. Опасная наивность. Нашел сегодня баг, где я спокойно складываю пустые строки, и получаю строку “null”! Причина в том, что первая строка оказалась null, а вторая - “”. Случалось это редко, поэтому нашел только сейчас, спустя три года.
Какая тут мораль? Доверяй, но проверяй? Не. Лучше так: и эти люди иногда катят бочку на PHP?!
Помните выражение "тесты как документация"? Типичный случай сейчас был.
Для таких простеньких функций тесты поначалу кажутся ерундой, но это опасная ошибка. Тесты эти простейшие, пишутся за минуту, а помощи много еще при написании функции - придает уверенности в реализации краевых случаев(пустые строки и т.д.).
В дальнейшем эти тесты вроде бы сильно пользы не приносят, поскольку функции эти менять мало кто будет, но кушать не просят, выполняются за наносекунды, поэтому нет проблем. Зато если ктото вздумает поменять - сразу помогут пресечь ошибки. Но я сейчас не об этом.
Захотел я вспомнить как эта функция себя ведет в некоторых кейсах(а писал я ее больше 3 лет назад) - просто сделал Find Usages и прямо в этом окне сразу увидел все, что нужно. Даже не заглядывая в тесты. Документация!
Начал потихоньку готовить код Laravel Idea к работе в команде. CI с прогоном тестов и проверкой на совместимость со штормом уже давно стоит. Второй по важности пункт - натравить на проект проверятор стиля кода и тоже гонять его в CI. Несмотря на кажущуюся малую полезность, для командной разработки это чуть ли не must-have. Договориться разок о стиле(а то и деспотично назначить самому 😈), прописать в конфиге стайл-фиксера, и все. Если поддержка в IDE есть - совсем шик.
В пхп есть php-cs-fixer. В СиШарпе помню лет 10 назад был StyleCop. Для Котлин есть detekt.
Первый прогон - 2900+ ошибок. Борюсь с ними сейчас. Довел до 428.
Встретил тут один каламбур, отчего и решил написать этот пост. Function getModelFqnDeeply is nested too deeply.
Не стоит забывать о правиле Парето. Иногда очень простые в реализации фичи могут экономить кучу времени пользователям и добавлять ценности продукту в разы больше, чем фичи, на которые убиты месяцы.
Сделал одну вот фичу и сижу думаю: а что мешало ее сделать давным-давно?
/channel/laravel_idea/38
Купил я как-то молока в 4-литровой бутылке. Думал так удобнее будет. В итоге, моя 48кг жена заставила меня наливать из этой бутыли при каждой необходимости, ибо ей тяжело. Мораль проста: прежде чем принять решение - подумай о других членах команды)
Когда я работал на галере, пришел в новую команду и там сразу же мне говорят “Слушай, у нас тут проект один есть… его написал реально крутой чел, но из команды уже ушел. И у нас никто не может код понять, а задач для него уже набралось прилично”. Я посмотрел, там C#, монады верхом на функторах и безграничная функциональщина. Данные красиво летают от функции к функции и получается результат. Но понять код - это настоящий challenge.
Вероятно, примененный подход был хорош и подходил к задаче идеально, но bus factor для этого проекта равен 1. А когда человек ушел - проект стал неподдерживаемый. Не всегда надо тащить самые продвинутые техники или игрушки, с которыми хочется поиграть(монады) в реальный проект.
P.S. Мне конечно понравилось тогда ковыряться и задачи делать для этого проекта, но я запомнил это как одно из самых деструктивных решений для команды.
P.P.S Некоторые поняли этот пост как “не тащи ничего нового в проект”. Нет. Тащить надо, но подумав как это адаптировать в команде, а не наплевав на них)
Помню когда скринил этот класс сюда было много критики, что все методы начинаются как isSomething(). “Не по английски”. Исправил. Доволен)
Вообще, довольно важно находить мотивашку даже на такие вот мелкие улучшения, как переименования методов по-английски. Это один из показателей того, что тебе не плевать на проект/продукт.
Или того, что тебе больше нечем заняться.
Вообще не понимаю идею генерации changelog из гит коммитов. Она везде проскакивает. Есть даже готовая команда в шаблоне для плагинов от JetBrains. Это для совсем уж ленивых. Текст в коммите - для команды продукта, чтобы было понятно что и как конкретно сделано. Текст changelog - для юзеров. Если юзеры - это такие же php-програмисты, то наверно им будет понятен текст коммитов для юзаемого ими php-пакета.
Но как только аудитория и команда не совпадает по языку, фреймворку и т.д., то ситуация становится совсем другой. Всем интересна фича сама по себе, а не как она была сделана. И уж тем более всем по барабану на рефакторинги или оптимизации.
Другой вариант - генерить из тасков багтрекера. Это уже чуть более солидно, так делают сами JetBrains. Пример. Но это тоже для ленивых. Мало кому из юзеров интересно такое читать. Поэтому они делают более user-friendly страницы типа этой - https://www.jetbrains.com/phpstorm/whatsnew/
Каждый раз перед релизом я копирую текст всех коммитов с предыдущего релиза в одно место и пишу из них текст changelog для новой версии. Делаю текст хоть немного более маркетинговым, более понятным для юзеров. Хочу пробовать ещё видео записывать для каждого апдейта. Считаю это достаточно важным. Не стоит лениться сообщать юзерам о фичах более красиво, если вам или, хотя бы, им не плевать на продукт.
Ничего нет более постоянного, чем временное?
Отмазка хреновеньких проггеров, которые сделали кое-как и забыли. Либо префекционистов-вредителей, которым надо сделать сразу все правильно и красиво.
Намного проще сделать таску как можно более простым способом, немного(!) подумав о возможных изменениях и насколько тяжело будет в будущем поменять. А когда будущее настанет - найти в себе силы, мужества, смелости, но скорее всего банальной мотивашки реально изменить “временное” решение под новые условия.
P.S. В комментах справедливо возмутились, что виноваты часто не программисты, а менеджеры. Вероятно, это даже правда, но так ли важно кто виноват? На любом проекте, даже вроде как со строгими менеджерами, я, если видел дерьмецо, которое мешает жить, правил его, и часто просто никому не сообщал, что кроме реализации тасков занимался ассенизацией. За все 17 лет никто еще не возмутился.
Позволю себе в пятницу небольшой более казуальный совет. Очень помогают в некоторых ситуациях мульти-курсоры. А делаются очень просто. Кликнуть Option(Alt). Потом еще разок, но уже зажав клавишу, стрелкой вверх или вниз плодим курсоры.
Каждый курсор весьма самостоятельный: у каждого свой буфер для копипаста и это позволяет даже сложные вещи делать. Весьма регулярно пользуюсь.
Всегда старался уделять время таким вот фичам. Не сказать, что сэкономят много времени, но некий вау-эффект(“Ого какой софт умный!”) - он важен.
Читать полностью…Берем камень и отсекаем все лишнее
Многие знают про избитый совет про дорожки в парке. Он про то, что не стоит пытаться изначально продумать дорожки в парке. Правильнее сначала дать людям протоптать тропинки и потом на месте тропинок делать асфальтовые дорожки.
Не так давно стал в программировании придерживаться того же. Вот встречается задача, которая не решается в лоб: не сразу получается продумать где какая логика будет лежать и как обьекты будут друг с другом общаться. Раньше я принимал это как вызов! Тратил кучу времени, строя в голове великие конструкции, эпохальные ООП-дизайны, которые частенько оказывались плохими на практике. Я помню как мы могли часами, а иногда и сутками “продумывать дизайн” на первой работе.
Сейчас я стал делать проще - решаю задачу самым простейшим и тупым способом. Если надо скопипастить код - иногда тупо копипащу. Делаю так, чтобы тесты прошли. Фича сделана. Дальше можно оглядеть получившего зверя. На рабочем коде не только все недостатки дизайна видны лучше, но и намного понятнее как это исправлять. Иногда, кстати, бывает так, что оставляю этот вариант.
Главный недостаток этого метода - нужна дисциплина, чтобы не бросить зверя как он есть 🙂
Бывает иногда - один if поставишь маленький, потом второй такой же недалеко. Потом true или else части понадобились в другом месте. Все идет на уровне 1-2 строк, и кажется, что все под контролем. Потом эти два if появляются в другом месте, но тела у них немного другие. Не каждый опытный глаз обнаружит проблему, особенно когда все разбито на методы и эти однострочные if и else глаза практически не мозолят.
Это бомба замедленного действия. Когда-нибудь все равно долбанет. Появится новое требование и все это взорвется комбинаторным взрывом 🙂 Так оно произошло сейчас у меня, причем я даже не подозревал проблему пока это не случилось.
Все эти куски логики - отдельные обьекты. If - это либо фабрики, либо декораторы. Как только все это раскидаешь по правильным обьектам - станет сильно легче дышать.
Признак будущих проблем: два и более метода взаимодополняющих друг друга, или используемые в похожих ситуациях, в отличие от других методов класса/интерфейса. Если они появились в абстрактном классе или интерфейсе и начали множиться по наследникам - жди проблем. Решение: красиво выделить их в отдельный объект или объекты.
Был в Laravel Idea кусок кода, который раздражал. 150-200 строк некрасивых, которые разбирали все возможные вариации Route::resource(<тут names, only, except>)->only()->names() подобную вот конструкцию и получали из нее список имен роутов. Я несколько раз думал рефакторить этот кусок, но всегда убеждался, что там все слишком завязано друг на друге и нормально отрефакторить нереально.
Ситуация сильно поменялась когда пришлось добавлять абсолютно такой же саппорт для пакета роут-атрибутов от Спати. Там логика один в один, ибо они тупо редиректят логику в обычные роуты. И внезапно оказалось, что рефакторить можно! Быстро появилась куча вещей, которые есть и там и там. Выделил класс, который занимается обработкой общей логики. Все сильно упростилось и в процессе нашел пару багов(там сильно краевые случаи, но тем не менее).
Мораль: не всегда хватает скилла увидеть возможность отрефакторить-упростить код. Иногда нужен помощник в виде новых требований. Не всегда понятно, что надо выделить интерфейс, пока не получишь другой вариант реализации. Примеров полно. Проггеры иногда кидаются в рефакторинг просто так, без нужды и не имея какой-либо опоры и делают его совсем не так. Кароч, пока не чешется, лучше не чесаться - татарская мудрость.
Получила развитие ситуация с негативом Тейлора Отвела к разработчикам, использующим бренд Laravel в своих продуктах.
Сегодня с утра в американских газетах было объявлено о судебных исках компании Laravel против множества частных лиц и компании. Их обвиняют в нарушение прав интеллектуальной собственности на торговую марку Laravel в сети Интернет. Известно, что обвинения предъявлены: Spatie — у них под сотню пакетов, использующих бренд Laravel (Laravel Permission, Laravel Ignition, Laravel Medialibrary и т.д.), Caleb Porzio — за Laravel Livewire, Spartner — Laravel-Excel, а также множеству других лиц и компаний.
Первоначально было известно и о Barry vd. Heuvel, но, как говорят, он успел переименовать свои пакеты в Debugbar for Laravel и IDE Helper Generator for Laravel и его исключили из списков.
В рунете пока известно о двух людях, получивших иски. Это Andrey Helldar за Laravel Lang и Adel за Laravel Idea.
Общую сумму ущерба Отвел оценил в десятки миллионов долларов, заявив: «Люди, которые используют подобные поделки, думают, что их написал я. Ведь они называются Laravel. А это моя зарегистрированная торговая марка. Только я могу получать за неё деньги! Это мой Laravel. Я его придумал и написал. Не нужно за мой счёт зарабатывать себе славу и деньги. Это опенсорс — либо ты помогаешь мне, либо уходи! Создай свой уникальный бренд и зарабатывай на нём. Вы отнимаете хлеб у моих детей.»
На данный момент известно, что Гитхаб закрывает все репозитории, принадлежащие обвиняемым лицам. Позже они будут либо удалены, либо переданы компании Laravel.
Буквально вчера сайт, которым я пользуюсь почти каждый день, сделал одну из типичных ошибок новичка! Удивленью моему предела нет.
Эта ошибка новичка - использование системы авторизации для всех проверок. Авторизация, если грубо, это система, которая скажет, что у юзера не хватает прав выполнить такое-то действие. Но народ любит пихать туда всякие проверки, конкретно прав юзера не касающиеся. В ларавеле это прям тот еще бич, правда там больше пихают в форм-реквесты, но смысл ошибки тот же. Люди стесняются делать проверки бизнес-логики отдельно, но это единственный вариант сделать нормально и проверку и юзера уведомить правильно.
Проверки в стиле “нельзя опубликовать пустую статью” или “нельзя купить, если у тебя денег нет” надо делать отдельно от всех этих чисто инфраструктурных вещей типа валидации юзерского ввода или проверки прав юзера.
Конкретно мой пример: chess.com дает бесплатно порешать 5 шахматных задачек. Когда я попытался решить шестую он, вместо нормальной ошибки стал выдавать “Insufficient permissions” и больше ничего! Ладно я сразу понял прикол, но рядовой юзер вообще в шоке наверно был)
P.S. Исправили уже сегодня. Молодцы.
P.P.S. Мне не жалко премиум купить, но я тогда по полдня буду эти задачи решать) Покупал уже…
В твиттере третий день обсуждают этот код. Его выложили как откровенно плохой, но куча народу написало что он практически идеален.
Хороший пример, когда изначально код кажется слишком топорным, но стоит представить любой другой аналог - он будет сильно хуже в плане читаемости. Да, если надо будет как-то от числа 10 отойти, то придется переписать, но обычно такой код лежит себе и лежит, никому не мешает и всегда понятно, что делает. Идеален, в общем.
Можно придраться к тому, что первые условия(> 0.0, >0.1) и так всегда будут true, но диванные твиттерские компиляторщики сказали, что оптимизаторы нынче умные и этот код оптимизнут тоже.
Это я фиксил те 2900+ ошибок стиля, которые нашел detekt. Больше половины - автоматические замены(форматированием IDEA и маленьким своим пхп-скриптом), но и самому пришлось поработать.
В процессе нашел пару мелких багов. Плюс это вынудило меня на рефакторинг, который давно хотел. Центральный класс для кодогенерации был со сложный лайф-циклом. Создавался с дефолтными значениями(допустим базового класса), потом они менялись на те, которые настроил юзер. И потом каждый раз приходилось это все пересчитывать. detekt ругнулся что-то вроде "тут мутабельный список, который можно еще и перезатереть - выбери что-то одно" и это меня добило)
Теперь все иммутабельное, пересчитывается на лету. Вместо codeGeneration.baseClass
, теперь codeGeneration.getBaseClass(settings)
. Со стороны можно сказать, что стало хуже, но теперь все явно(нужны настройки, чтобы получить базовый класс) и цикл жизни простой - это неизменяемый объект с дефолтными значениями, но перекрываемыми из настроек.
На душе стало приятно. Но все это время меня преследовало сомнение - а стоит ли оно того? Наша профессия очень далека от прямых денег. Если продажник вместо работы два дня будет стол свой протирать - бизнес быстро заметит просадку. Так же как и более эффективные тактики.
Проггер же может два дня стилизовать код, делать рефакторинг и уверять, что это принесет плоды в будущем, а как проверить? Код в деньги превращается очень медленно. Поэтому, крайне сложно составить эффективные метрики работы программистов. Я пока не видел ни одной рабочей.
ChatGPT - новая разработка от OpenAI. Такого логичного обьяснения от человека сложно получить. Все еще уверены, что писать код - это перспективная профессия?)
С одной стороны, он обучается по коду, написанному людьми. Что-то по-настоящему уникальное ему врядли подвластно. Но та идиотская ситуация, когда десятки, а то и сотни тысяч программистов реализуют одни и те же алгоритмы, наконец может хоть как-то разрешиться в будущем.
/channel/tg_5minphp/1008
Ох как любит народ оптимизировать такты процессора и байты оперативки. Особенно, когда это не нужно) На реальном хайлоад веб-проекте оператор new будет где-то в конце третьего десятка причин тормозов. Там тормоза в основном из-за I/O - базы данных, кеши, диски. Банально закешить грамотно запрос будет в миллионы раз эффективней, чем убрать какой-нибудь new.
Я до сих пор с содроганием вспоминаю как смотрел видео, где один из core-разрабов yii2 делал метрики и доказывал, что код без интерфейсов выполняется на наносекунды быстрее, поэтому “интерфейсы не используйте” (https://youtu.be/x7-G4tHFSj8?t=1809 - вот здесь).
Бывают, конечно, задачи называемые “числодробилками”, где I/O операций мало, зато куча вычислений. Но это весьма и весьма нетипичная для PHP задача и часто ее выделяют и реализуют отдельно на каком-нибудь go (отсюда и мода на него в последние годы).
Одним из стабильных холиваров среди разработчиков является - как хранить деньги. Либо какой-нибудь decimal(*,2): доллары - целая часть, центы - дробная, либо integer - просто количество центов.
Я тут за инты. Банально потому, что насколько я знаю, по закону нет такого понятия как дробная часть копейки. Тут должна быть жесткость. А децималы позволяют иметь эту дробную часть. По крайней мере в переменных в коде.
Однако, при работе с целыми числами-копейками надо быть весьма осторожным. Их очень легко принять за рубли или доллары. Вот недавно волосы дыбом встали от таких коммиссий. 1750 долларов за перевод - звучит страшно). А на самом деле это 17,5 доллара. Вообще, надо иметь хороший Value Object-класс Money и через него работать.
P.S. Это баг в приложении одного банка. Некритичный, но неприятный)
Скопировал if, чтобы немного изменить поля и обратил внимание на это предупреждение. В очередной раз меня поразил ум IntelliJ IDEA.
Она поняла что если уcловие сверху выполнится, то defaultPath поменяется и такое же условие уже всегда будет false. Иногда это может помочь поймать очень неявные баги. Я помню где-то год назад смотрел доклад Тагира Валиева, который главный там по этим предсказаниям и умным инспекциям. Он рассказывал про случаи когда народ жаловался на эти инспекции, они садились и вместе выясняли, что это реально в коде баг.
Кому заходят ИТ-баттлы, то недавно вот выпустили - https://www.youtube.com/watch?v=4_Q1ck1gRx0
“PHP: Фреймворки против Битрикса” Саша Макаров отбивается от битриксоидов. Прослушал немного по диагонали. Аргументы в стиле “а в Yii всё через массивы и вообще никаких бест практис”, “рынок требует Битрикс”(видимо российский рынок имеется ввиду) и т.д., а потом они ушли обсуждать фронтенд (что как-то странно соотносится с темой).
Мотивация путем уменьшения неопределенности
У каждого из нас бывает - сидишь, смотришь в экран, вроде бы работаешь, но постоянно отвлекаешься на ерунду. В поток войти никак не получается. А вечером обнаруживаешь, что сделано очень мало. Недавно нашел полезную корреляцию: таких состояний намного меньше, если есть четко определенная цель.
Реализуй эту фичу или пофикси баг - далеко не всегда четко определенные цели. У фичи могут быть полно деталей, а у бага несколько возможных причин или целый лабиринт вероятностей. А еще бывает назначают кучу тасков и сложно определиться какой делать 🙂
На этой неопределенности очень легко уйти в прокрастинацию, или в другие наклонности, которые приведут к вышеописанному состоянию бездействия. Совет: как можно быстрее уменьшить неопределенность почти до нуля. Идеальный способ - написать тесты. Превратить неопределенную цель “сделать фичу” в почти 100% определенную - сделать тесты зелеными. С багом тоже самое - написать тест, который его репродуцирует и желательно во всех вариациях. Таска сделана - со следующей тоже самое, на остатках мотивации как можно быстрее сделать тесты.
После этого намного проще сосредоточиться. Есть ясная цель - сделать тесты зелеными. Она помогает. По крайней мере, я уже несколько раз выходил из того состояния благодаря этому.
P.S. Другой очевидный способ уменьшения неопределенности - бить большую задачу на маленькие.
Переработал первую главу книги. Она стала сильно структурированнее, ну и добавил довольно много всякого материала. Даже подглаву про преждевременную оптимизацию. Странно, что я это не описал ранее. Вот небольшой отрывок из добавленного текста:
Замечаете один и тот же шаблон? Разработчик принимает неудачное решение, которое кажется удачным поначалу. По мере усложнения проекта это решение все больше и больше усложняет жизнь. Вместо того чтобы собрать волю в кулак и признать, что решение было плохим, разработчик не исправляет его, а исправляет лишь его последствия, что делает код все хуже и хуже. Одним из главных умений разработчика является то шестое чувство, когда начинаешь понимать, что твой код "сопротивляется" изменениям - не хочет меняться легко и плавно, а требует все больше и больше усилий, заплаток и сделок с совестью для реализации таких изменений. Почувствовав такое сопротивление, надо искать его причины, найти те самые неудачные решения в дизайне кода, и исправить их. Это сделает проект намного более податливым к следующим изменениям. Именно это шестое чувство и позволяет большим проектам долго оставаться на плаву, не превращаясь в то самое "легаси", которого мы все стараемся избежать при приеме на работу.
Если вдруг кто-то захочет почитать главу - https://github.com/adelf/acwa_book_ru/blob/master/manuscript/1-bad-habits.md
Если все еще используете вкладки редактора в шторме или других средах от JetBrains, то рекомендую попробовать от них отказаться. Года три назад я их выключил ради эксперименту и с тех пор не включал.
Очень мало кто по вкладкам переключается клавишами - итогом идет активное использование мыши(тачпада), что снижает продуктивность.
Вместо этого можно использовать Ctrl(Cmd)-E и просто выключить вкладки за ненадобностью. В том же окошке очень хорошо работает поиск. Крайне рекомендую.
Убрать вкладки: Preferences(Settings) | Editor | General | Editor Tabs | Tab placement: None.
Такое чувство, что люди очень странно понимают слова “more expressive”. Первый вариант четко говорит о том, что будет возвращен обьект редиректа на такой-то роут. А Нуно здесь очень понравилось “return to_route”, но это больше прикольно, чем реально полезно.
И, конечно, комменты в стиле “ОГО! Я теперь могу писать на несколько символов меньше!”. 🙊 Сразу видно, кто использует продвинутые средства разработки, а кто нет )
Лара-коммунити частенько так удивляет…