Нервный программист
176 subscribers
87 photos
2 videos
1 file
50 links
Эмоционально об айти и программировании
Download Telegram
В догонку к предыдущему посту. Поставил еще bun, pypy (python реализация с jit) и ruby!

Ну что могу сказать. Bun очень удивил! 🤩

0.22418 +- 0.00369 seconds

У ноды, напомню, было 0.32645. Так что это наш новый чемпион!

Окей, я подумал, что может рил влияние запуска самой ноды на столько велико. Ведь я мерию perfом, а он измеряет выполнение команды. Добавил в сам скрипт временные метки. И нихрена подобного. У bun это в среднем около 0.20 секунд. У ноды 0.30 секунд. То есть, и там, и там на запуск и всякое остальное тратится +/- одно и тоже время.

Так шо bun рил топ! 👍

А что там с pypy? А наконец-то все как у людей

0.346620 +- 0.000672

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

Ну и чисто по фану, запустил Ruby (3.2.3).

20.0148 +- 0.0176 seconds

Чуток быстрее питона -- уже хорошо. Ожидаемо.

Рубисты сорри. Я вообще не рубист. Я пытался поставить yjit и у меня он не собрался чет с первого раза. А по скольку "собрать из исходников" -- единственый варик у них в доке, то пошли они нахуй я забил.

Кароче, первый вывод. Если у вас jit, то че то вычислять числами будет плюс-минус одинаково везде. Но только если это не bun. Bun -- мое почтение! 🫡 А если у вас не jit, то пхп вам напихает за обе щеки (привет python и ruby).

Второй вывод: первый вывод -- это вывод из жопы. Не надо воспринимать его серьезно. Мы тут чуток в циклах числа посчитали. Это мягко говоря не все вычислительные задачи. Так шо похер. Все чисто for fun.

И последнее. У пхп с jit просто отвратительный разброс по таймингам

0.2980 seconds
0.2284 seconds
0.3182 seconds
0.2904 seconds
0.2707 seconds
0.3137 seconds
0.2628 seconds
0.2971 seconds
0.2144 seconds
0.2786 seconds

от Bun до nodejs. Нигде больше такого нет, у всех все стабильно с точностью до 2го знака.
2
You use Mojo. I use Bython. We are not the same.
🔥8😱4😁2
Любой пхпшник знает, что топовая IDE это джетбрейнсовский phpstorm. Сорри любители Vim с LSP, но это горькая правда🥲 И недавнее исследование от джетбрейнс 🤡 это подтверждает. Кстати, ставьте лоис, если хотите обзор на возможности сторонней lsp (phpactor) для пхп. Или не ставьте. Как хотите, кароч, я все равно сделаю.

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

Проблема в том, что я уже несколько раз натыкался на баги, связанные с некорректным анализом кода. И тут вы мне скажете "да ты охуел! у всех есть баги!" Но прикол в том, что эти баги не вчера зарепортили люди. И создается впечатление, что никто их не торопится фиксить. Например, как вам вот такой баг из 2023 года. Если вкратце, то в этом коде

$a = ['a'];
$b = ['b'];
$c = [...$a, ...$b];

шторм будет считать, что у $c тип string[][], хотя должно быть string[]. Это в дальнейшнем приводит к false-positive ошибке в редакторе, что очень бесит. И вот в конце 2025го я вынужден использовать array_merge при работе со списками😡

Поэтому я решил проверить свое ощущение и узнать, а как вообще у джетбрейнс обстоит дело с фиксом багов, которые им пользователи приносят. Благо, что у них вполне себе открытые release notes и трекер. В youtrack надо поставить фильтр Subsystem: PHP Inspections, чтоб получить тикеты связанные с анализом пхп. Вот для 2023 года (178 штук), а вот для 2022 (286 штук).

Чекнул релиз ноуты за 2025 год. На момент написания поста, актуальная версия 2025.2.4. Получилось, что в этом году они не исправили ни одной проблемы из 2023 года, исправили 1 тикет из 2021 и 1 тикет из 2022. Это было все в одном релизе 2025.2. И это довольно печально😢

Конечно я не продакт в джетбрейнс, и не мне приоритеты выставлять, чем занять разрабов завтра. Но как минимум мне кажется странным, что почти все тикеты имеют приоритет Normal (процентов 90), либо Nice to have. И только два (тикета, а не процента) имеют приоритет Major. Но, сука, и их никто не торопится фиксить 🤡

Мне странно видеть у всех багов пользователей приоритет Normal. Баги же разные бывают. Некоторые чисто косметические и на них можно забить, а некоторые куда серьезнее. Например, вот этот тикет влияет на возможности рефакторинга. Люди в комментах бампают его, но как-то всем насрать. Проприетарная безысходность...

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

Вот такая осенняя грустняшка сегодня😰
7👍5
Литералли мой гитхаб
😁10🤣8💅21
Сегодня жители Санкт-Петербурга могли видеть ярко красное зарево. Это полыхала моя срака после попыток стать pro python девелопером😡

В чем суть. Потребовалось разработать новый сервис. К сожалению его специфика вновь заставила использовать python вместо любимого пхп 😢

Очень часто можно услышать мнение что стандартный пакетный менеджер pip - говно из жопы. Типа он медленный, всратый, не позволяет разделять зависимости на группы, нет лок файла и прочее. Короче говоря, устаревший инструмент. И это не безосновательно.

И вот комьюнити напряглось и родило новый пакетный менеджер uv, который blazingly fast (написан на rust 😍), в котором куча всяких фич, который за тебя готовит виртуальные енвайронменты и прочее. Короче, слышал про него только хорошее.

Подумал, что говорят про него достаточно долго и много, поэтому можно его попробовать затащить в прод. Покурил доку. Вроде бы все выглядит как нормальный пакетный менеджер. Есть pyproject.toml файл, в котором описываются зависимости с требованиями к их версиями, аналог composer.json и package.json. Есть uv.lock, в котором прям точные версии пакетов описываются. Есть команды для установки, удаления, обновления пакетов. Короче, все как мы любим, и все работает реально быстро. Так что же тогда могло так сильно поджарить жепу?

Давайте вспомним, как мы готовим наши проекты для прода. Обычно одним из этапов билда является команда вроде yarn install --frozen-lockfile --production, которая ставит все зависимости из лок файла без development. И вот аналогом такой команды в uv является команда uv sync --frozen --no-dev. Это команда создает venv со всеми зависимостями из лок файла, кроме дев зависимостей.

А дальше вопрос, как запускать наше приложение? Дла этого используется команда uv run. Она сама активирует текущий venv со всеми зависимостями и запустит ваш скрипт. Так, например, рекомендуют запускать uvicorn в докере.

И вот разработчики решили, что будет АХУЕННО крутой идеей при запуске uv run
* проверять, что лок файл соответствует toml, и если нет то обновлять его
* проверять, что venv соответствует лок файлу, и если нет то обновлять venv

Блять, я готов ставить свое сгоревшее очко на то, что когда вы запускаете uv run app.py вы не ожидаете, что у вас че-то будет меняться в лок файле или в venv. Ибо это команда для ЗАПУСКА. Окей, мы поставили все прод зависимости с помощью uv sync --frozen --no-dev, затем выполнили uv run на старте контейнера, и у нас подтянулись все дев зависимости🤡збс! и чтоб этого не случилось, нужно добавлять флаг --no-sync.

И такое "ожидаемое" не только меня сбивает с толку. Считаю, что делать такое было мега тупой идеей. Ибо ни в одном другом пакетном менеджере я не припомню такого поведения. Сук, ты выдай лучше ошибку! Че ты бесиш то! 😡

А так в целом конечно blazingly fast и очень круто 👍

Ну давайте, питонисты, напихайте мне в комментах, что я неправ и команда запуска - отличное место, чтоб обновить venv 😢
😁11🔥3🤡2
Обожаю эту дихтомию синхронного и асинхронного питона. Когда там завезли в питон asyncio? А я вам скажу, когда! async/await - это python 3.5. И это спокойный 2015 год😌То есть 10 лет назад вселенная питона расщепилась на "до" и "после". И вот "после" код в питоне заиграл новыми красками. Во всех смыслах, включая появление т.н. цветных функций.

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

Вот и у меня щас немножк вылезло. Собственно пишу я сервис для сбора и экспорта продуктовых метрик в prometheus. Если посмотреть на список официальных SDK, то выяснится, что список ЯП ограничен следующими экземплярами: Go, Java, Python, Ruby, Rust. Поскольку я все таки хочу стать pro python developer'ом, мой выбор был предопределен.

Вот только когда я читал доку по SDK, я че то не заметил, что кастомный коллектор, который мне и нужен, - это синхронный генератор. А у меня асинхронное приложение 🤷

Ну как бы понятно, что это не супер большая проблема. У нас есть целых 3 варианта, как действовать:
* Сделать синхронный кэш метрик, который периодически обновляется асинхронно, а коллектор забирает данные синхронно
* Использовать ThreadPoolExecutor и вынести запросы в бд в отдельный тред прям в коллекторе
* Переписать все на Rust, чтоб было blazingly fast

На самом деле выглядит, как рабочий момент. Придется немношк поприседать. Ничего, бывает. Так что сегодня жопа не горит☺️

А к чему это я вообще говорю. Я на фоне этого всего вспомнил, что в php планируют завезти true async👍 Предвкушаю адский пердолинг на годы вперед, если примут 🤩
💯1
Внимание! Наконец-то стало известно, как работает все это ваше веб айти!
😁8🤣5
Ну штош. У нас тем временем очередная глобальная уязвимость в мире js под названием Shai-Hulud 2.0. Npm держит марку! красавцы! 👍

Подробности вы можете почитать в статье, но если вкратце, то
* Shai-Hulud это червь, который заражает npm пакеты
* Это делается посредством внедрения preinstall скрипта setup_bun.js
* Скрипт ворует все креденшиалы на локальной машине, включая npm креденшиалы, и публикует их в гихаб репозиториях
* Далее публикуется зараженая версия пакета в npm
* Поскольку в мире js все пакеты зависят от всех, это говнище быстренько распространяется на другие пакеты

Кароч пиздос! npm немношк пора поменять правила публикации новых версий. Как будто не стоит надеяться на то, что люди сами будут использовать 2FA.

Слава богу сегодня не обновлял пакеты😌
2👍1🙈1
Вчера сходил на пыхап и выиграл еще двух слоников. Теперь у меня их 4. Но на фото их почему-то 5🤷
🥰64🔥4😁2
Лол. Мне это напомнило недавние новости от майкрософт о том, что они наконец-то скоро пофиксят медленную загрузку проводника. Знаете как? Они будут в фоне предзагружать его🤡
🤡5🤮2
Возвращаясь к этому мему про схему веб айти. Не знаю как вам, а мне все слова на этой картинке знакомы. Кроме одного - left-pad. И я решил чекнуть, что это такое. Внезапно выяснилось, что за этим скрывается целая восхитительная история под названием npm left-pad incident. Го читать пересказ википедии ниже.

Для начала, что такое этот ваш left-pad. А это npm пакет. По сути, это одна функция из 11 строк, которая дополняет строку слева до нужной длины. Можно указать, каким символом дополнять. Например

leftPad(12, 5, '0')
// => "00012"


Исходно создал этот мощный пакет разработчик по имени Azer Koçulu. Для простоты я буду звать его Андреем. Андрей был плодовитым опен сорс разработчиком из Калифорнии. Поговаривают, что он был мейнтейнером более 270+ пакетов в 2016 году. Одному из его пакетов не повезло получить имя kik.

Дело в том, что в то же самое время развивался и набирал популярность мессенджер с одноименным названием kik. Его разрабатывала компания, с названием состоящим из 3х букв. Угадайте название. Подсказака: буквы k i .

И вот ребята из этой компании решили использовать npm для создания своего собственного пакета под кодовым названием kik. Но попытка сделать это полностью провалилась, ибо Андрей уже застолбил имя. Что делают корпораты, когда какой-то человек мешает им делать бизнес? Правильно, они приходят к нему и говорят "проваливай, петушара"😡

Так и решили поступить адвокаты компании с Андреем. Сначала они написали ему письмо, в котором тупо попросили переименовать свой пакет во что-нибудь другое. Андрюша прихуел с такого поворота, но сказал, что он не будет ничо переименовывать. Тогда компания пошла на второй заход, и написала ему что-то вроде "Андрей, если ты нахуй щас же не переименуешь свой пакет, наши адвокаты постучатся сначала к тебе во входную, а потом и в заднюю дверь. Понял, ты, говно-жопа?" Андрей совсем не оценил такого мува, и резонно решил послать компанию на 3 буквы (не k i k).

После этого ребята из кика решили пойти к ребятам из других 3х букв n p m, и попросили передать имя kik им во владение. На удивление, две компании быстро пришли к согласию, и вот 18 марта 2016 года Андрей получил извещение о том, что имя kik таки у него забирают. 4 дня Андрей провел в полных ахуях. В конце концов окончательно психанув, просто удалил нахер все свои 270 пакетов из npm, и написал, что он рот топтал такой опен сурс. Среди этих пакетов был и left-pad.

Ой, что тут началось! После такой "шутки" Андрея лежали всей маршруткой всем интернетом. Внезапно выяснилось, что пакет left-pad, который на гитхабе в то время имел всего 11 звезд, был прямой и непрямой зависимостью других пакетов. Например, пакета react 🤡 В тот день на 2.5 часа легли билды у таких небольших компаний как фейсбук, пейпал, нетфликс, спотифай.

Поскольку после удаления left-pad имя пакета освободилось, другой разработчик тут же создал клон оригинального пакета с тем же названием. Но версия у пакета по правилам npm должна была отличаться. Так шо это ничо не починило.

По итогу фиксинга npm высрали пост, где среди прочего написали npm won’t suddenly take your package name. Твердо и четко! В остальном же сослались на то, что лицензия пакета была MIT, так что код принадлежит всем. Поэтому пусть комьюнити делает форки и засталбливает названия оригинальный пакетов Андрея. Ну а они постараются сделать процесс анпаблишинга пакетов тяжелее, и обещают предотвратить публикацию зараженных пакетов🤡

Вот такая история. Знали о ней? За кого вы, за Андрея или за npm? должно ли имя пакета следовать принципу наименьшего удивления и принадлежать соответствующей компании пусть даже в ущерб нервным клеткам одного разработчика?

я просто в 2016м еще был нормальным парнем, и фронтендом особо не интересовался. Так что этот бриллиант прошел мимо меня.
🔥121😁1😱1
Ну шо, реактеры, признавайтесь, сколько у вас провайдеров?
😁5👏2
Знаете, что общего между Егором Бугаенко и Артемием Лебедевым? И тот и другой много чего рассказывает. И у того, и у другого 50% это база, но другие 50% это откровенная дичарня.

Ладно, на самом деле я со всем уважением к Егору. У чувака опыта больше в 2 раза, его производительность видна на гитхабе, он пишет книги, читает лекции и его слушают. Так шо аргумент "сначала добейся" кажется мне уместным здесь. Но, думаю, я имею право не согласиться с ним в чем-то.

Около полугода назад попался мне ролик, где Егор отвечает на вопросы. И его там спросили, как он относится к DI - контейнерам. И он сослался на свою старую статью, и отметил, что его позиция с тех пор не изменилась. Штош, вот она эта статья под громким названием Dependency Injection Containers are Code Polluters. Она довольно старая. Но раз Егор по-прежнему ссылается на нее, то и мы скидок делать не будем. Давайте ознакомимся.

В статье Егор сначала приводит пример DI через конструктор, рассказывает на сколько это полезно по сравнению с инстанцированием зависимостей внутри класса. Ну допустим, тут мы верим, хотя Егор заканчивает объяснение фразой No need to discuss why. It’s obvious. Причем obvious - это ссылка stackexchange 😂 Так бы и написал "мне лень объяснять, давайте там сами, заебали".

"So far so good, but here comes the dark side—a dependency injection container" -- говорит нам Егор далее. Ну надеюсь щас нам расскажут про темную сторону.

После этого он вводит понятие DI-контейнера на примере старой библиотеки Google Guice, которая в данный момент не поддерживается. Удивительно, но оказывается, что если у тебя в приложении всего 2 класса, один из которых - это зависимость другого, то написать new A(new B()) окажется короче, чем конфигурировать контейнер! Вы знали об этом? Я ахуэл!

Кроме того, Егор отмечает, что существуют еще сценарии неправильного использования DI-контейнера такие как
* Field injection
* Setter injection
* Passing injector as dependency
* Making injector a global singlton (чем это плохо, кстати?)
И далее Егор заключает "If we put all of them aside, all we have left is the constructor injection explained above. And how does that help us? Why do we need it? Why can’t we use plain old new in the main class of the application? ... The container we created simply adds more lines to the code base, or even more files, if we use XML. And it doesn’t add anything, except an additional complexity."

Ну собственно все! Вот и вся аргументация! спасибо за внимание, нахуй!

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

Лан, на самом деле это еще не все. В конце Егор нам приводит пример Right way. Там гигантская портянка кода, которая не влезет никуда, поэтому ее кусок я ввиде скриншота приложил. Знаете, программирование - это в каком-то смысле квинтэссенция принципа "красота в глазах смотрящего". Егор смотрит на этот код и видит Right way, я смотрю на этот код и вижу клубень говна. Какие-то блять волшебные константы, ни одной повторяющейся зависимости. Где логер, Егор? В любом приложении он есть. Как ты его со своим right way собираешься вкорячивать?

О, я кстати придумал аргумент. "Егор, ну и чем твой код лучше XML? А?" Раунд!

Ладно, если по серьезке, то статья просто гавно! не потому что Егор там глобально неправ (хотя и это тоже), а потому что он свою позицию никак не раскрыл. Даже если бы он просто взял свой right way и переделал с использованием DI-контейнера, и вот там уже указал на additional complexity, и где конкретно она появляется -- в этом уже был бы толк и предмет для дискуссии. А так ну это просто наброс.

Хотел свое мнение написать про di-контейнеры, но че то разбобмбился знатно, пока пост писал. Да и так про них много написано. Ну может потом. "мне лень объяснять, давайте там сами, заебали"

А вы как, согласны с Егором, что di-контейнеры - это зло?
👍81🤗1
Решил вчера вернуться на десктопный линукс после 5 лет перерыва. Поставил кубунту. Перезагрузился 2 раза - все ок. На 3й раз увидел вот это.

Годы идут, а к десктопному линуксу как нельзя было без вазилина прикасаться лет 10 назад, так и до сих пор нельзя. Оплот стабильности😊 зато будет, чем заняться в это воскресенье.

PS. Да, я подозреваю, что это какая-то проблема с grub, secure boot и тем, что это вторая система. Но все равно прикольно, что на ровном месте приключения. Винда кстати норм грузится🤷
👍32
Карочи, опять про питоновский линтер pylint. Не буду повторять (хотя повторю), что в наше время, если линтер не умеет сам ошибки исправлять, то это немношк кринге. Ну да ладно😔

Седня хотел поговорить про конкретное правило линтера, а именно про порядок импортов. У нас есть стандарт PEP8, который декларирует следующие группы импортов:
1. Импорты стандартной библиотеки
2. Импорты сторонних либ
3. Локальные импорты
Группы импортов должны размещаться в начале каждого файла именно в таком порядке. Они должны быть разделены пустой строкой. Код должен идти после. И pylint по дефолту требует выполнения этого условия. Вроде норм, но! Импорты не реордятся автоматически 😡

Есть такая функция из модуля dotenv, называется load_dotenv(). Любой сеньор догадается, что эта функция занимается тем, что загружает переменные окружения. Поэтому, мы ее где нить в начале скрипта вызываем, и дальше у нас все окружение доступно.

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

SERVICE_HOST: Final[str | None] = os.getenv("SERVICE_HOST")
if SERVICE_HOST is None:
raise RuntimeError("SERVICE_PORT is not set далбаеб")


Вроде нойм. Но вопрос, а куда воткнуть load_dotenv()? Вы можете подумать, что load_dotenv надо воткнуть сразу после импортов в рутовом файле приложения. Ну типа, это начало "как бы" кода. Но в таком случае, мы сразу получаем ошибку, потому что наш import service окажется до load_dotenv() и переменные не будут загружены на момент выполнения импорта. Ведь питон просто исполняет код внутри файлов по мере поступления импортов.

И тут получается 2 стула:
* Либо мы вызываем load_dotenv() в каждом таком файле с env переменными после импортов, и pylint счастлив
* Либо мы втыкаем его между импортами прямо перед группой локальных импортов в рутовом файле

Во втором случае у pylint сгорает срака. Потушить ее можно поместив все локальные импорты между дtрективами # pylint: disable=wrong-import-position и # pylint: enable=wrong-import-position (см. скриншот кода из прода 😱).

Я че то думал-думал, и решил, что load_dotenv() в каждом файле это какая-то параша. Хоть вызов load_dotenv() несколько раз на корректность не влияет, вроде как оно замедляет старт скрипта. Но я не бенчмаркал🤷 Поэтому выбрал второй варик.

И тут многие проженные питонисты скажут "Ррряяя, ты туповатый. Надо делать отдельный класс-хранилище переменных, который ты будешь инициализировать на старте. У тебя опять skill issues!". Не кипятитись мои горячие питонячие пирожочки. Тут важно еще раз обратиться к цели: скрипт не должен даже стартануть, если какой-то конфиг пропущен. Я не должен узнать об этом в рантайме. И все должно быть типизированно. Никакое класс-хранилище эту проблему не решит.

Или я неправ? Делитесь в комментах, как у вас дела обстоят с енв переменными. Или напихайте мне за высосанную из пальца проблему! 😘
4
Блин, такая вообще обида у меня щас конечно😢 аж до слез!

На прошлой неделе тюнил потребление памяти в нашем монололитном макросервисе на symfony. Че то оно было подозрительно высокое. И обнаружил, что в какой-то момент бэкграунд джоба загружает из базы массив на 200 000 интов. Чтобы подсчитать их количество🤡 Ну это ладно. Думаю, все так делают.

Чтоб достать это все из базы, используется доктриновский getSingleColumnResult(), который возвращает лист со значениями одного столбца. И в этот момент потребление памяти подскакивает до 60 мб, шо как бы нихуясебе. Ну и вы можете сказать "а че ты хотел. 200 000 интов в массиве на пхп, это тебе не шутки!"

А давайте все таки прикинем писю к носу потребление памяти для такого списка. Любой скаляр в пхп занимает 16 байт, потому что именно столько занимает zval. И тут, как математик, я вам могу сказать что, (16 х 200 000) / 1024 / 1024 = 3мб. И с этим уже можно жить. И если, как физик, я создам такой лист с нуля, то примерно такое потребление памяти я и увижу. Но откуда 60 мб? Стало быть, какое-то непотребство происходит внутри доктрины.

Стал разбираться и быстро выяснил, что под капотом у getSingleColumnResult() используется PDOStatement::fetchAll c флагом PDO::FETCH_NUM. Этот флаг возвращает результат в виде списка списков с одним элементом. Таким образом, доктрина была поймана за руку, как дешевка! Ведь у каждого массива в пхп есть оверхед в пару сотен байт. Вот оно и вылазиет.

Тут же созрел хитрый план, что на выхах я буду врываться в опен сурс со своим классным пулл реквестом, где заменю флаг на PDO::FETCH_COLUMN. И меня тут же все полюбят, и я стану красавчиком, наконец😌

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

Вот так провалилась очередная попытка стать классным😢

Выводы:
* Жизнь - жестокая штука
* Своевременность - это очень важно
* За любым массивом кроется память

Спасибо, что выслушали ❤️
👏12😁64👍3
Сорри за прошлонедельный боян, но я не мог пройти мимо этого.

Наконец-то кто-то сможет положить конец этой бездушной корпорации!
😁52🤯1
Ну что, мои дорогие бомбята! Вот и наступил 2026. Я не очень люблю итоги года, поэтому всех просто поздравляю. Надеюсь все выжили и готовы активничать дальше. Может не прям сегодня конечно😊

Думаю 2026 год даст не меньше поводов побомбить, чем 2025. А это значит, будет о чем написать, и что обсудить. Я, в свою очередь, обещаю, что контент, как и прежде, останется человеко-генерированным, но не всегда полезным) Но я щитаю, что польза - это про другие каналы. Здесь я скорее про фан и эмоции вокруг нашего любимого программирования. Ну и всегда рад показать, что обосраться - это не зазорно, а иногда и очень здорово 😀

Всех с новым годом! 🥳 Хорошо отдохните, шоб сделать врыв в следующий год максимально мощным!

P.S. Праздничный кот Кристофер передает всем привет
14🎉10💯1
Литералли каждый коммент, когда вайбкодю:
😁4🤔1