Пишу на Котлине и радуюсь null-safety. Везде он прикроет, не даст получить NullPointerException и все прекрасно. Опасная наивность. Нашел сегодня баг, где я спокойно складываю пустые строки, и получаю строку “null”! Причина в том, что первая строка оказалась null, а вторая - “”. Случалось это редко, поэтому нашел только сейчас, спустя три года.
Какая тут мораль? Доверяй, но проверяй? Не. Лучше так: и эти люди иногда катят бочку на PHP?!
Какая тут мораль? Доверяй, но проверяй? Не. Лучше так: и эти люди иногда катят бочку на PHP?!
Буквально вчера сайт, которым я пользуюсь почти каждый день, сделал одну из типичных ошибок новичка! Удивленью моему предела нет.
Эта ошибка новичка - использование системы авторизации для всех проверок. Авторизация, если грубо, это система, которая скажет, что у юзера не хватает прав выполнить такое-то действие. Но народ любит пихать туда всякие проверки, конкретно прав юзера не касающиеся. В ларавеле это прям тот еще бич, правда там больше пихают в форм-реквесты, но смысл ошибки тот же. Люди стесняются делать проверки бизнес-логики отдельно, но это единственный вариант сделать нормально и проверку и юзера уведомить правильно.
Проверки в стиле “нельзя опубликовать пустую статью” или “нельзя купить, если у тебя денег нет” надо делать отдельно от всех этих чисто инфраструктурных вещей типа валидации юзерского ввода или проверки прав юзера.
Конкретно мой пример: chess.com дает бесплатно порешать 5 шахматных задачек. Когда я попытался решить шестую он, вместо нормальной ошибки стал выдавать “Insufficient permissions” и больше ничего! Ладно я сразу понял прикол, но рядовой юзер вообще в шоке наверно был)
P.S. Исправили уже сегодня. Молодцы.
P.P.S. Мне не жалко премиум купить, но я тогда по полдня буду эти задачи решать) Покупал уже…
Эта ошибка новичка - использование системы авторизации для всех проверок. Авторизация, если грубо, это система, которая скажет, что у юзера не хватает прав выполнить такое-то действие. Но народ любит пихать туда всякие проверки, конкретно прав юзера не касающиеся. В ларавеле это прям тот еще бич, правда там больше пихают в форм-реквесты, но смысл ошибки тот же. Люди стесняются делать проверки бизнес-логики отдельно, но это единственный вариант сделать нормально и проверку и юзера уведомить правильно.
Проверки в стиле “нельзя опубликовать пустую статью” или “нельзя купить, если у тебя денег нет” надо делать отдельно от всех этих чисто инфраструктурных вещей типа валидации юзерского ввода или проверки прав юзера.
Конкретно мой пример: chess.com дает бесплатно порешать 5 шахматных задачек. Когда я попытался решить шестую он, вместо нормальной ошибки стал выдавать “Insufficient permissions” и больше ничего! Ладно я сразу понял прикол, но рядовой юзер вообще в шоке наверно был)
P.S. Исправили уже сегодня. Молодцы.
P.P.S. Мне не жалко премиум купить, но я тогда по полдня буду эти задачи решать) Покупал уже…
Просто предупреждаю о том, что сегодня 1 апреля. А то народ уже забеспокоился, что Тейлор меня засудит и бросился спрашивать что со мной будет теперь)
Forwarded from Laravel World
Получила развитие ситуация с негативом Тейлора Отвела к разработчикам, использующим бренд 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.
Сегодня с утра в американских газетах было объявлено о судебных исках компании 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.
Где-то в ноябре я решил побыть настоящим свободным художником и поработать в шезлонге у бассейна. Но судьба быстро дала понять, что всю жизнь мне суждено быть офисным или максимум домашним работником. Пацану лет 3 было скучно и он окатил мой ноут с водяного пистолета. Я успел посидеть там минуты две) Тогда с ноутом ничего не произошло, но на днях моник просто погас и все.
Отнес на ремонт - поменяют материнку, займет две недели. Там остались незапушенными 3 коммита. И я 2 дня вспоминал что в них было. Вспомнил. Восстанавливаю.
Мораль - пушьте свою работу в гит. Он в том числе и для этого создан.
Отнес на ремонт - поменяют материнку, займет две недели. Там остались незапушенными 3 коммита. И я 2 дня вспоминал что в них было. Вспомнил. Восстанавливаю.
Мораль - пушьте свою работу в гит. Он в том числе и для этого создан.
Был в Laravel Idea кусок кода, который раздражал. 150-200 строк некрасивых, которые разбирали все возможные вариации Route::resource(<тут names, only, except>)->only()->names() подобную вот конструкцию и получали из нее список имен роутов. Я несколько раз думал рефакторить этот кусок, но всегда убеждался, что там все слишком завязано друг на друге и нормально отрефакторить нереально.
Ситуация сильно поменялась когда пришлось добавлять абсолютно такой же саппорт для пакета роут-атрибутов от Спати. Там логика один в один, ибо они тупо редиректят логику в обычные роуты. И внезапно оказалось, что рефакторить можно! Быстро появилась куча вещей, которые есть и там и там. Выделил класс, который занимается обработкой общей логики. Все сильно упростилось и в процессе нашел пару багов(там сильно краевые случаи, но тем не менее).
Мораль: не всегда хватает скилла увидеть возможность отрефакторить-упростить код. Иногда нужен помощник в виде новых требований. Не всегда понятно, что надо выделить интерфейс, пока не получишь другой вариант реализации. Примеров полно. Проггеры иногда кидаются в рефакторинг просто так, без нужды и не имея какой-либо опоры и делают его совсем не так. Кароч, пока не чешется, лучше не чесаться - татарская мудрость.
Ситуация сильно поменялась когда пришлось добавлять абсолютно такой же саппорт для пакета роут-атрибутов от Спати. Там логика один в один, ибо они тупо редиректят логику в обычные роуты. И внезапно оказалось, что рефакторить можно! Быстро появилась куча вещей, которые есть и там и там. Выделил класс, который занимается обработкой общей логики. Все сильно упростилось и в процессе нашел пару багов(там сильно краевые случаи, но тем не менее).
Мораль: не всегда хватает скилла увидеть возможность отрефакторить-упростить код. Иногда нужен помощник в виде новых требований. Не всегда понятно, что надо выделить интерфейс, пока не получишь другой вариант реализации. Примеров полно. Проггеры иногда кидаются в рефакторинг просто так, без нужды и не имея какой-либо опоры и делают его совсем не так. Кароч, пока не чешется, лучше не чесаться - татарская мудрость.
Наше PHP-коммунити составило списки интересных каналов. Можно добавить сразу пачку и они добавятся в вашу телегу отдельной папкой и даже не будут содержаться в основном списке(будут заархивированы по умолчанию, удобно)
PHP (Rus) — https://t.me/addlist/R7i3akzlB2kwZTMy
PHP (Eng) — https://t.me/addlist/yNksksLVT6M5NGEy
PHP (Rus) — https://t.me/addlist/R7i3akzlB2kwZTMy
PHP (Eng) — https://t.me/addlist/yNksksLVT6M5NGEy
В первый раз попросил ChatGPT реальный код написать для меня. Аккуратно ему описал что нужно и он с первого раза дал то, что надо. Тестов я, конечно, написал сам. Когда попросил его написать тест - он написал прям плохой. Без краевых случаев. Очередное доказательство, что он ничего не понимает.
Такие простые задачки для него идеальны. На самом низком уровне написать алгоритм, на который он 100% натыкался, когда анализировал какой-нибудь stack-overflow(если даже на другом языке - он наверняка справится). Я пробовал для прикола просить у него что-нибудь более высоко-уровневое - бесполезно. С генерацией текстов для git-коммитов - тоже самое. Если в коде немного абстракции - сообщения он генерит абсолютно бесполезные.
Вывод: помощник он неплохой. Позволяет хорошо сократить время на что-либо, но надо понимать ограничения.
Такие простые задачки для него идеальны. На самом низком уровне написать алгоритм, на который он 100% натыкался, когда анализировал какой-нибудь stack-overflow(если даже на другом языке - он наверняка справится). Я пробовал для прикола просить у него что-нибудь более высоко-уровневое - бесполезно. С генерацией текстов для git-коммитов - тоже самое. Если в коде немного абстракции - сообщения он генерит абсолютно бесполезные.
Вывод: помощник он неплохой. Позволяет хорошо сократить время на что-либо, но надо понимать ограничения.
Давно хотел перевести книгу https://github.com/adelf/acwa_book_ru обратно на английский и нашел идеального переводчика - ChatGPT. После него править почти не надо. Решил еще разок проревьюить её - добавить всякие новые фичи, которые появились в PHP за эти 3-4 года. Ну и дописать пару мыслей. Приведу тут пару отрывков нового.
То, что я описал здесь, очень похоже на архитектурный шаблон Гексагональная архитектура, или Луковая архитектура, или еще десятки подобных. Неудивительно, поскольку они решают ровно те же задачи. Однако, гораздо полезнее для развития разработчика самому осознать причины выделения кода в отдельные классы, почувствовать какие части кода могут работать с базой данных или данными веб-запроса. Самому увидеть как участки кода с похожими обязанностями и потребностями выстраиваются в некое подобие слоев.
Получив подобный опыт и набив руку, можно ознакомиться с данными шаблонами и, возможно, принять один из них как стандарт на каком-либо проекте, полностью осознавая, что данный шаблон подходит проекту, не являясь микроскопом, коим забивают гвозди или пушкой, которой стреляют по воробьям.
Выделение слоя приложения - весьма ответственный шаг и причина должна быть серьезной. Их всего две:
1. Разные интерфейсы к одним и тем же действиям (Web, API, Console, различные боты). Тут вынесение общей логики просится само.
2. Разросшиеся и сложные логики обработки веб-запроса, например, и бизнес-логики. В данном случае разделение логик по разным местам может заметно улучшить связность кода. Как правило, это ведет к повышенной багостойкости кода.
То, что я описал здесь, очень похоже на архитектурный шаблон Гексагональная архитектура, или Луковая архитектура, или еще десятки подобных. Неудивительно, поскольку они решают ровно те же задачи. Однако, гораздо полезнее для развития разработчика самому осознать причины выделения кода в отдельные классы, почувствовать какие части кода могут работать с базой данных или данными веб-запроса. Самому увидеть как участки кода с похожими обязанностями и потребностями выстраиваются в некое подобие слоев.
Получив подобный опыт и набив руку, можно ознакомиться с данными шаблонами и, возможно, принять один из них как стандарт на каком-либо проекте, полностью осознавая, что данный шаблон подходит проекту, не являясь микроскопом, коим забивают гвозди или пушкой, которой стреляют по воробьям.
Выделение слоя приложения - весьма ответственный шаг и причина должна быть серьезной. Их всего две:
1. Разные интерфейсы к одним и тем же действиям (Web, API, Console, различные боты). Тут вынесение общей логики просится само.
2. Разросшиеся и сложные логики обработки веб-запроса, например, и бизнес-логики. В данном случае разделение логик по разным местам может заметно улучшить связность кода. Как правило, это ведет к повышенной багостойкости кода.
PHP-народ сегодня активно обсуждал нововведение в PHP 8.3 -
В 8.3 это будет просто полезная для стат-анализаторов или больших проектов штука, которая поможет отследить, если в классе-родители метод удалили, а наследники будут продолжать думать, что они чтото переопределяют у родителя.
Поговаривают, что в 9 или 10 версиях это может стать обязательным. Но обязательным оно наверняка станет одновременно и с обязанностью в классе-родителе указывать то, что метод может быть переопределен. Как в Котлине, Яве и куче других языков. В котлин если метод неабстрактный, но может быть переопределен в потомках, надо указать ключевое слово open.
Для чего, кроме строгости, это нужно? Для оптимизации вызовов этих методов. Методы, про которые мы знаем точно, что их никто не перекрывает, вызывать легко. В давние стародавние времена я разбирался с тем, как выглядит вызов обычного и виртуального(так назывались те, которые можно перекрыть) методов в C++ коде(от C++ Builder компилятора). Ассемблер код вызова простого метода(забьем на параметры) - call method <aдрес где сидит код того метода>
Вызов динамического - найти в обьекте ссылку на таблицу виртуальных методов, там найти указатель на нужный метод, и вызвать метод. Для тех времен это была серьезная оптимизация, поэтому виртуальными старались делать только те методы, которые надо.
В PHP все методы виртуальные - их можно перекрыть. Но если ввести обязательное указание виртуальности метода(open/override или както иначе), то можно получить более оптимальный опкод. Насколько большим будет прирост на реальных проектах судить не берусь. Понимаю только, что это очень серьезный BC - ломает совместимость прям сильно. Сомневаюсь, что на это пойдут.
#[Override]
атрибут. Такой же как в Java. Он позволяет указать тот факт, что этот метод перекрывает метод у класса-родителя. Подробнее по ссылке - https://t.me/sergei_predvoditelev/33В 8.3 это будет просто полезная для стат-анализаторов или больших проектов штука, которая поможет отследить, если в классе-родители метод удалили, а наследники будут продолжать думать, что они чтото переопределяют у родителя.
Поговаривают, что в 9 или 10 версиях это может стать обязательным. Но обязательным оно наверняка станет одновременно и с обязанностью в классе-родителе указывать то, что метод может быть переопределен. Как в Котлине, Яве и куче других языков. В котлин если метод неабстрактный, но может быть переопределен в потомках, надо указать ключевое слово open.
open fun method()
и тогда в классе-потомке можно будет его переопределить override fun method()
- тот самый override. Для чего, кроме строгости, это нужно? Для оптимизации вызовов этих методов. Методы, про которые мы знаем точно, что их никто не перекрывает, вызывать легко. В давние стародавние времена я разбирался с тем, как выглядит вызов обычного и виртуального(так назывались те, которые можно перекрыть) методов в C++ коде(от C++ Builder компилятора). Ассемблер код вызова простого метода(забьем на параметры) - call method <aдрес где сидит код того метода>
Вызов динамического - найти в обьекте ссылку на таблицу виртуальных методов, там найти указатель на нужный метод, и вызвать метод. Для тех времен это была серьезная оптимизация, поэтому виртуальными старались делать только те методы, которые надо.
В PHP все методы виртуальные - их можно перекрыть. Но если ввести обязательное указание виртуальности метода(open/override или както иначе), то можно получить более оптимальный опкод. Насколько большим будет прирост на реальных проектах судить не берусь. Понимаю только, что это очень серьезный BC - ломает совместимость прям сильно. Сомневаюсь, что на это пойдут.
Forwarded from Laravel Idea
Некоторые уже в курсе, что мы с JetBrains сделали общий bundle, в котором пользователи могут купить шторм вместе с плагином со скидкой. За подробностями сюда.
Картинку взял с корейского обьявления. Там логотип Laravel Idea кажется самым главным)
Картинку взял с корейского обьявления. Там логотип Laravel Idea кажется самым главным)
Пятничная мелкая тактика. Сделал тут мини-рефакторинг и решил выложить. Вначале присвоение
Вообще,
Иногда крайне сложно разглядеть такую мелкую "логику". Но буквально минуты через две как вынес этот метод, я нашел, что правильнее делать это не через метод
Мораль: разной логике(даже мелкой) лучше лежать в разных местах. Оно облегчает изменения и улучшает будущий код.
isEnabledAndVisible
казалось незаметной мелочью и проблемы видно не было. Но когда метод подрос, стало понятно, что это все-таки две логики: посчитать нужно ли показывать экшен и "присвоить" результат. Из-за лаконичности Котлина второе не казалось чем-то важным.Вообще,
isEnabledAndVisible
это котлиновский сахар. На самом деле он превращается в вызов Java-метода setEnabledAndVisible
, который сам по себе просто сахар над вызовом двух методов.public void setEnabledAndVisible(boolean enabled) {
setEnabled(enabled);
setVisible(enabled);
}
Иногда крайне сложно разглядеть такую мелкую "логику". Но буквально минуты через две как вынес этот метод, я нашел, что правильнее делать это не через метод
update
, а по-другому, и вынесенный метод сразу же пригодился там. Мораль: разной логике(даже мелкой) лучше лежать в разных местах. Оно облегчает изменения и улучшает будущий код.
Недавно сделал рефакторинг, который выглядит дико даже для меня, но в итоге, подумав, вполне нормальный.
Был класс, который размещал два компонента в окошке. Обычно это label и поле к нему. Но иногда там был только label и тогда field было null. И наоборот могло быть тоже. В итоге была огромная конструкция где проверялись все возможные варианты - кто null, кто не null. А когда добавились еще параметров стало просто невмоготу.
Что я сделал? Вместо одного класса FieldPair, в котором оба поля могли быть null, я сделал три. OnlyLabel, OnlyField and FieldPair. И в каждом только ненулевые компоненты. И все стало так сильно проще! Я даже мелкий баг нашел сразу же.
Был класс, который размещал два компонента в окошке. Обычно это label и поле к нему. Но иногда там был только label и тогда field было null. И наоборот могло быть тоже. В итоге была огромная конструкция где проверялись все возможные варианты - кто null, кто не null. А когда добавились еще параметров стало просто невмоготу.
Что я сделал? Вместо одного класса FieldPair, в котором оба поля могли быть null, я сделал три. OnlyLabel, OnlyField and FieldPair. И в каждом только ненулевые компоненты. И все стало так сильно проще! Я даже мелкий баг нашел сразу же.
https://gist.github.com/adelf/bf9e8d6d094e5c01c24689e4c92ce9c5
Простой пример реального Value Object на Котлин(из кода Laravel Idea). Скрывает свое содержание. При сравнении не учитывает регистр. Ну и еще пару фич в нем. Раньше все в строке хранил в формате "схема.таблица", но стало сложно управляться. Теперь намного проще.
Благодаря equals&hashCode, Java/Kotlin умеет их использовать в качестве ключей массива(Map) и таблички в разных регистрах спокойно работают. Удобно.
Простой пример реального Value Object на Котлин(из кода Laravel Idea). Скрывает свое содержание. При сравнении не учитывает регистр. Ну и еще пару фич в нем. Раньше все в строке хранил в формате "схема.таблица", но стало сложно управляться. Теперь намного проще.
Благодаря equals&hashCode, Java/Kotlin умеет их использовать в качестве ключей массива(Map) и таблички в разных регистрах спокойно работают. Удобно.
Gist
DatabaseTableName Value Object
DatabaseTableName Value Object. GitHub Gist: instantly share code, notes, and snippets.
Сегодня приснился кошмар. Я попал на работу в крутую компанию. Начал писать какой-то функционал и написал тест. Менеджер начал мне обьяснять как добавить этот тест в их систему. Надо взять бланк, описать название теста, на каких кейсах его запускать. Потом понести этот бланк на другой этаж к админам! Получить от них одобрение, инвентарный номер теста(!!!), поставить подписи и все! Менеджер всю дорогу хвастался насколько удобен этот процесс)
Я сидел там у админов и не верил в происходящее. Номер мой тест получил 347. А система огромная! Значит тестов почти не пишут. Понятно почему)
Мимо проходил знакомый, мы поздоровались и я сказал "Вот коллегой твоим стал, но видимо ненадолго"
Я сидел там у админов и не верил в происходящее. Номер мой тест получил 347. А система огромная! Значит тестов почти не пишут. Понятно почему)
Мимо проходил знакомый, мы поздоровались и я сказал "Вот коллегой твоим стал, но видимо ненадолго"
О трудностях разработки плагинов. Я начинаю поддержку новой мажорной версии шторма сразу как только выходит EAP. Соответственно ориентируюсь на ранние релизы. Но где-то между 2023.1 и 2023.1.5 они переместили классы в другой неймспейс) Это нормально сделать между мажорными версиями, поскольку эти классы помечены как экспериментальные, и что они могут меняться. Но не между минорными же! Такое очень сложно поддерживать...
Здесь пришлось просто не использовать эти классы. Отложить их до 2023.2 и надеяться, что такого не случится еще разок
Здесь пришлось просто не использовать эти классы. Отложить их до 2023.2 и надеяться, что такого не случится еще разок