Про фреймворки
Здравствуй, дорогой дневничок.
Я так понимаю, это уже становится формой закономерности: если публикации стали появляться все чаще и чаще, значит какая–то основная большая работа завершена, и появляются окошки для креатива. Собственно, так всё и происходит, и настоящий момент как всегда глубин и воодушевляющ, и осознание последствий трудов своих праведных безусловно приятно и духоукрепляюще. Я в этом смысле достаточно давно поймал один важный инсайт, который несколько раз озвучивал в том или ином виде, о том, что уверенность в себе достигается результативностью собственных действий. И в основе этого — доведение результата собственных дел до требуемого уровня, в котором можешь твердо и четко сказать себе “я сделал!”, не переживая о том, что там будут обнаружены какие–то косяки или оно быстро придет в негодность, едва только будут подписаны акты выполненных работ и закончится гарантийный срок.
И будучи уверенным в том, что путь не только узнан, но и пройден, и теперь очень хорошо знаешь, как если что его можно повторить, можешь твердо и четко заявлять о своей компетентности в указанном вопросе и предлагать сопутствующее этому вопросу решение, которое знаешь как делать. А что делать, если не знаешь как делать, а делать как–то надо? И как быть уверенным в том, что будет достигнут именно требуемый результат, а не тот, что будет назван требуемым ввиду неизвестности более лучшей версии как таковой? И как быть, когда сталкиваешься с фактом того, что собственноручное достижение, которым так гордился, является лишь жалкой поделкой по сравнению с чьим–то еще большим трудом, автор которого сам не слишком доволен результатом, и хочет его улучшить еще.
Ох уж этот перфекционизм! То ли патология, то ли исконное чувство прекрасного и безусловного стремления к лучшему, которое всегда враг хорошего. И если сам знаешь, что можно лучше, то уже не так уверен в том, насколько хорошо достигнут текущий результат. И в этом смысле так странно выглядит чья–то чужая самоуверенность в том, что его неаккуратная поделка является достойным поводом для собственной гордости. Тот самый парадокс Даннинга–Крюгера, когда профессионал знает о слабых местах большой системы и принимает осторожные шаги, чтобы их обойти, не торопя события и перепроверяя исходные данные, чтобы не ошибиться в расчетах следующего шага, в то время как молодой энтузиаст, освоивший базовые принципы, и радующийся собственному прогрессу, твердо и четко уверен в своих силах изменить мир вокруг себя к лучшему, и поэтому смело двигается по всем граблям одновременно, тщательно уворачиваясь от предлагаемых ему вызовов, бросаемых самому себе.
В этом смысле со стороны профессионала, наблюдающего за ходом чьих–то стратегических мыслей и тактических действий можно либо старательно не обращать внимания на чужие ошибки, повторяя классическое “пилите, Шура, пилите”, продолжая точно также работать над собственным шедевром, удаляя всё лишнее и оставляя только необходимое. А можно и забить себя фейспалмами и то и дело срываться бить по чужим рукам, которые не подумав лезут в концептуальные дебри, откуда потом будут долго и искренне спрашивать у всех и каждого “а как так получилось?”. Кто бы мог подумать!
Расскажу несколько историй про компьютерную разработку, которые то и дело шатали мою собственную уверенность в том маневре, который я сам совершаю, денно и нощно нянчась с собственным кодом в сопутствующих практике проектах. Но начну немного издалека, а именно с глубокого заблуждения, которое я очень по–своему понял, услышав когда–то словосочетание REST Layer, которое по классике означало совсем не то, что я подумал. А подуманного ведь уже не откатишь: мысль зародилась, идея зажглась, инсайт был получен и работа началась. Я тогда активно писал на PHP, и как раз вышла пятая версия, позволяющая делать рефлексии над классами и прочие обобщенные абстракции над свойствами и методами, а также появились более–менее нормальные замыкания, которые можно было прокидывать по контексту.
А я до этого еще долго возился со своей ORM, которой мог лазать в “произвольную” базу, и делал типизированную возможность прокидывать данные в шаблон, чтобы не ограничивать себя одним Smarty, если на то была необходимость или требование по легаси. В общем, шел параллельным курсом с созданием типовых фреймворков с традиционной методологией MVC и иными модификациями общепринятых принципов. При этом, что характерно, моя методология в общем и целом совпадала с той, которой держался мейнстрим, и моя функциональная классификация была достаточно близка к общепринятой, хоть и с небольшими поправками. Более того, я достаточно долго не был знаком с концепцией React–а и прочих Angular–ов, и пилил собственную версию каскадного server side rendering–а, в котором дополнительно решались проблемы прав доступа, объединения и разделения контекстов и прочие насущные задачи, с которыми я регулярно сталкивался в требованиях к софту и которые эволюционно накапливались в виде готовых решений, благодаря которым я с очень уверенным лицом выполнял чьи–то заказы и получал за это деньги. И никто на свете не мог меня переубедить перейти на Zend и прочие Yii, какими–бы популярными они ни были. В них просто не было на борту тех супер–удачных плюшек, которыми я в моменте закрываю кучу актуальных задач.
Например, когда–то удачно разработанная система управления правами доступа, ограничивающая запуск тех или иных функций или проверяющая возможность отображения тех или данных на интерфейсе сохраняет свою генеральную идею до сих пор, обнаруживая при этом полную несостоятельность делать что–то подобное в других популярных решениях, обязывая там городить такой страшный логический огород, что её часто просто не берутся решать, оставляя различные дырки в системе безопасности, в которые потом влезают отчаянные мамкины хацкеры, справедливо считающие себя умнее прочих. Точно также обнаружилось, что созданный мною подход контроля данных для передачи их в серверные шаблоны, который хоть и обязывал меня писать какую–то пользовательскую логику на чистом js, не пользуясь более реактивными компонентами, прекрасно сохраняет свою основную функциональность и в простой генерации JSON–данных, которые быстро и корректно выгружаются на произвольно взятый клиент, принимая их в шаблоны конкретно взятого программного стека. И так было всегда: когда популярные решения становились доступными для того, чтобы на них можно было начинать писать что–то востребованное на рынке, мой собственный программный код уже обладал фишками, которых не было ни в одном из мейнстримовских решений, которые позволяли мне вести разработку быстрее любых конкурентов, какого–бы размера команда разработчиков там не была бы задействована. При этом я точно знал, что мое решение работает не хуже реализации на каком–то “классическом” подходе, и может быть лишено некоторых нюансов, но в общем и целом не лишено концептуальной логики, и сохраняет в себе пространство для развития.
В общем, для произвольно взятого бизнеса я представлял собой целый парадокс: с одной стороны высокая скорость и хорошая надежность конечного продукта, а с другой — невозможность заменить разработчика, потому что так как я пишу, больше никто не пишет. А специально переучиваться никто не будет. А тут еще и мое собственное выгорание и обнаружение каких–то более лучших идей, которые заставляли скептически смотреть на собственную ошибку выжившего, которой так гордился всё это время, и даже успешно конвертировал её в деньги.
В этом смысле я, как раз–таки, не метался от языка к языку, считая себя полиглотом, способным решать задачи на чем угодно, а сосредотачивался на чем–то, что откликалось на интуитивном и экспертном уровне как что–то, достойное того чтобы посвятить этому значительное число лет в жизни, и реализовать на нем всё задуманное, что сквозит сквозь форточки подсознания, наматываясь на опыт и практику, которые были всегда. И я очень рад тому, что не ошибся когда–то в своем выборе, остановив его на JavaScript, который смог в TypeScript и декораторы.
Сейчас расскажу, что за ситуацию я решал последние пару дней, и почему особенно доволен собой. Короче, делаю я сейчас новый проект, в котором активно используется telegram–бот. Я и раньше делал проект связанные с телегой, но они запускались в старой архитектуре и были вшиты в монолит, который всегда стартовал единым процессом, и всей этой херней пытался взлететь. А в последние годы я использую гибридный подход к запуску кода, когда в разработческой версии я могу стартануть весь код одной командой, а при запуске на боевом сервере разбить их на процессы, каждый из которых крутится сам по себе, и если что никого не ждет и может быть даже при необходимости запущенным на другой ноде, и обмениваться с остальными процессами через общую шину данных и кластер базы. Удобно и эффективно: всю разработку я веду с полным знанием о том, что если всё работает в целом, то оно как правило работает и в распиленном состоянии.
Но не всегда, иногда приходится хвататься за голову, обнаруживая какой–то крайне интересный и необычный баг, связанный чаще всего с циклическими зависимостями и некорректной последовательностью обращения к адресному пространству имен и их инициацией. То самое, когда еще не объявили, а уже пытаются пользоваться, и прочие баги второго и третьего порядка, которые видны не сразу, особенно на больших предметных областях, где множество справочников опирается друг на друга.
Короче, внезапно, после пары месяцев активной разработки, я обнаружил, что когда я запускаюсь в кластерном режиме, то бот создает столько параллельных подключений, на сколько сервисов я разбиваю запуск. А у него по правилам только одно допустимое подключение допускается. А мне в том числе надо к некоторым данным из этого подключения обращаться, и какую–то полезную информацию получать. И все это в нескольких разных API, которые крутятся сами по себе и не должны друг друга мешаться. И, казалось бы, столкновение с тем, что не вложено в коробку должно было заставить бить себя ссаными тряпками по голове, самобичуясь в том, что не предусмотрел такого очевидного момента, и теперь вся затея коту под хвост, но нет. У меня на этот счет вообще были далеко идущие планы по созданию удобного механизма переброса выполнения данных из изолированных процедур, к которым только и ждал момента приступить. Тем более, что удачных наработок достаточно для того, чтобы что–то делать наверняка, а не перебирая аналогичные решения, каждое из которых очень уж специфично само по себе, а мне надо чтобы оно именно особым образом выглядело. Собственно говоря, отдельно потраченный день, начатый с формирования требования к тому, как решение должно выглядеть, и на то, чтобы вписать в эти требования релевантный код, используемый в смежном кейсе — решили мою проблему, дав сразу возможность использовать это же решение в будущем, где оно точно пригодится. Я уже знаю несколько кейсов, где это требуется.
Я вообще очень интересно пишу код. Я не иду из того “вот у тебя есть что есть, и пользуйся этим как хочешь”. Я смотрю на решение скорее с художественной точки зрения. Что–то типа: вот эти вот штуки должны очень удобно сочетаться и выглядеть аккуратно, без лишнего нагромождения, и должно корректно рефакториться. И я сидел и как мог натягивал сову на глобус. Вместо того, чтобы есть что дают, где миллионы мух ну точно уж не ошибаются в том, где они зарабатывают не меньше моего, делая почти то же, что и я, я с упорством, достойного, возможно, лучшего применения пилил исходный код наперегонки с галактическим Шурой, стараясь допилить до конца раньше прочих. А там еще пилить и пилить. И мой код — это в первую очередь акт творения, в котором я легко и непринужденно мыслю о том, что хочу сделать, как достигаю этого результата.
В этом смысле у меня всегда главная сложность с тем, чтобы начинать работать с каким–то популярным фреймворком, который точно может делать то, что делают мои технологии, и оно очень даже похоже друг на друга. Но есть нюанс, который исторически там сложился, в виду легаси, версий, и прочих адаптаций по обе стороны фулл стека. И некоторые вещи, которые я решаю легко и непринужденно, вызывают в чужой эксплуатации чувство ярости от того, что меня заставляют думать об этом так сложно. Вот уж реально, когда правила системы если к ним привыкнуть вроде как позволяют с ними работать, но чувство от того, что стоишь всё это время в предельно неудобной позе никуда не девается. Хотя, есть подозрение, что другие этого просто могут не замечать, потому что оно всегда так было. И думать иначе там в самом деле никто просто так не умеет. Думание — это ведь тоже особая практика, и думание об одном и том же не есть думание о другом таком же. Везде мышление старается экономить на глюкозе и выдавать самые ленивые варианты решения, которые приходят в голову, чтобы не утруждать себя лишней нагрузкой. Особенно когда всегда приходится думать с этой нагрузкой, погружая свое внимание в сложность, самопорождаемой системой со всеми её правилами и ограничениями. Всегда хочется чем проще, тем лучше. А иногда не лучше, но мы предпочитаем об этом не думать или делать вид, что не знали.
Кстати, иронично то, что как тот же Nest появился, “эволюционировав” из Angular, так мой фреймворк имеет все шансы стать в первую очередь frontend–технологией, которой неважно с какими данными работать, и создающей свою собственную сетевую службу по обработке общего множества данных. Считать что–то на каждом клиенте и использовать результат в качестве показателей общего вклада в пользование сервисом. Что–то типа serverless + appserver. Это ведь само собой напрашивается: у нас огромное количество мощных устройств, которые это могут делать, и которые это уже постоянно делают. А мы тут вроде как байты. Осталось только прикрутить полезную нагрузку, и сможем интересно пользоваться своими устройствами и развивать их особым образом. Особенно на фоне вероятно дефицита полупроводников, где каждый доступный флопс станет подотчетным товаром, и на государственном уровне ограничивать предел пользования тремя мега–Тьюрингами, чтобы не слишком сильно фрактал шатать сингулярностью. А вот ведь оно там есть, и это как–бы ого.
Жду, когда тот же Chat GPT нормально подключат к интернету, и я смогу обучить её своим правилам кода, и запрашивать готовые модули. А оттуда и до создания визуального конструктора с динамическим редактором и системой плагинов и модулей недалеко. Оно там само напрашивается, я фактически всегда создавал именно это решение, и все больше и больше довожу его до ума. Безуспешно строя из себя Ахиллеса, гоняющегося за галактической черепахой, ползущей во все стороны одновременно. Кто ты, воин?
Причем, что характерно, даже если технологию кто–то автономно от меня подхватит и разовьет самостоятельно до нужного уровня, опубликовав все в open–source, то честь и хвала этим людям, кто упоролся на отличненько. То есть факта копирования и публикации технологии под другим названием, но с удачным сохранением и развитием главных заложенных принципов, которые объединились в более сложное и эффективное решение — это как бы нихуя себе личный вклад в общественное достояние. Я вообще за то, чтобы хорошие технологии были открыты людям, и те учились ими пользоваться с целью полезного применения, создавая технические решения для своих бизнесов, и объединяя удачные паттерны в систему плагинов, которые также можно продавать, в том числе в виде готовых решений.
Полагаю, сингулярность окончательно схлопнется тогда, когда будет сделано что–то типа интеграции с гитом, который будет встроен в другие экосистемы для возможности бранчевания проекта и актуализации исходного кода в новых версиях, и все это оплачиваться деньгами через платформы на этом же исходном коде. И все это на блокчейне. У–у–х! Сам пока не понимаю, как это будет выглядеть, но возможности доступны серьезные. Надо брать и делать, брать и делать.
Чем, собственно, и занимаюсь.
А тут еще занятно на этом фоне наблюдать беспомощность коллег по цеху, кто подряжался как–то созданные мною решения развивать и поддерживать. Мол, а как это оно так работает, что работает? И что если его переделывать, то там прям много чего такого знать надо, с чем раньше не сталкивались, и где можно легко ошибиться. А серьезный программист на окладе не может себе позволить рисков ошибиться в своих действиях. Это грозит большими репутационными потерями. Отсюда всё это постоянно делегирование на джунов, которым в случае чего и терять особо нечего, кроме собственного чувства ахуенности от того, что ему доверяют решать сложные задачи, и у него получается. Работает–же? Чего тебе еще от меня, собака, надо? И он внедряет все больше и больше собственных решений, делая больше и больше ошибок, которых можно было бы избежать, пойди он с самого начала другим путем.
У меня так получилась интересная ситуация с проектом MeetForCharity, где мне с самого начала была обещана доля за участие, а в итоге пришлось многократно прибегать к показательно осуждающему тону требуя не затягивать с выплатой денег, пусть даже не в том объеме, который изначально предполагалось заработать. Там вообще ситуация смешная была, когда заказчику предлагали совершенно абсурдные решения, в которых задача решалась только на бумаге, но не предлагалось никаких конкретных действий по реализации логического аппарата хранения и обработки собственно самих данных. А у меня на тот момент активно шел локальный эксперимент по миграции удачных решений из предыдущего проекта в локальных подрядах, где я в общем и целом сохранял сложную логическую функциональность и возможность быстрого рендера управляющих компонент через готовые решения и наработанные шаблоны. В итоге я стал тем, кто взял на себя оказание услуги по части разработки всей логики и бэкенда, на которую потом цеплялись мобильные приложения и браузеры. В итоге у меня получилось гибридное решение со своим внутренним рендерингом html и json под разные нужды. Монолит, но с нормальной возможностью роста и интеграции с какими–то дополнительными службами: платежные системы, чековые сервисы, отправка рассылок, и так далее. Возможности были заложены многие, хоть и выглядели не так, как в других учебниках по программированию. А если включить голову и начать разбираться, то быстро понимаешь что к чему, и действуешь соответственно.
Так ведь голову включать никто не любит. Надо или пиздить, или хитро заинтересовать, чтобы думать сами начали. Я и так и так стараюсь, но пиздить приходиться чаще. Потому что никто не любит включать голову без нужды.
Короче, после завершения первого этапа проекта мой исходный код ходил по разным рукам, по нескольку месяцев внедряя фичи, которые можно было бы сделать за пару дней, и все–равно все ключевые новые расширения переводя на меня, позволяя все дозаработать те деньги, на которые изначально был уговор. И даже немного больше. И всё это, прошу заметить, без какого–либо сопротивления реальности: заказчик — барин, может делать со своим продуктом что хочет. И сам принимать решения о том, кто из подрядчиков достоин его доверия и отвечает за результат и сроки. Очень может походить на манипуляцию, в которой я как–бы шантажирую своей уникальностью, которым никто в той же мере не владеет. С другой стороны я сам заинтересован делиться знаниями и развивать чужие мозги и чужое мышление. Потому что факт остается фактом — десятки молодых людей не решали стоящие задачи доступными им инструментами столь же эффективно, что и я, просто не имея за плечами сколь–либо похожего на мой опыт, и вынужденно учась думать в уже ограниченных условиях чужих сводов правил и паттернов, в то время как я даже с ассемблером успел поковыряться, хоть и не слишком успешно. И для меня исходный код начинается в первую очередь с выполнения требований на наличие требований к асинхронным вызовам и возможности безопасного хранения мета–атрибутов и быстрого к ним доступа. И прочей рефлексией, с которыми уже не первый год экспериментирую, и которая практически не нужна в обычной жизни, когда есть все готовое, но со своими нюансами.
Вот я и устраивал свой собственный бунт против системы, в первую очередь делая что–то красивое, что целиком и полностью устраивало в первую очередь меня, а только потом нуждалось в одобрении заказчика, которого я всегда честно и откровенно предупреждаю об особенностях предлагаемого мною решения. Гарантируя при этом достижимость заявленного результата в условленные сроки, каких не может дать ни один другой подрядчик, со всеми их agile–ами вместе взятыми. Потому что там думать надо уметь, и задачи специфические уметь решать, которые в нормальной жизни ни у кого не возникают, и мало кто хочет себе заказать конструктор собственных форм со специфической, пользуясь гораздо более простым функционалом, типовым для большинства бизнесов. Все эти онлайн–магазины, пользовательские кабинеты и прочая интеграция с amoCRM. Микросервисы как есть, и никто не умеет с ними работать, гоняя миллион одних и тех же данных в разные хранилища, и удивляясь, почему где–то что проебывается ввиду человеческого фактора, неспособного комфортно удержать такую логическую сложность в своей голове, и бессознательно блокирующего развитие неэффективного мышления. От того и по одной кнопке внедряют на дизайн в течение месяца, что здесь так принято, и так и должно и стоить. А я потом сильно удивляюсь, как можно столько времени тратить на обычную для меня операцию.
Сейчас так вообще интересный опыт намечается, когда заказчик, кинувший с партнерством, может очень интересным образом обнаружить сложность с его гипотезой о незаменимости людей в команде, и столкнуться с суровой реальностью, где всё дорого, и никто думать не хочет. Потому что думать не обучены, и из готовых плагинов как могут собирают что могут. А что не могут собрать, на то просто не тратят времени, или пытаются собрать из того что могут, называя это близким по смыслу, но со своими нюансами. А тут еще и дополнительный нюанс, что и код мой действительно хорош и работает стабильно и без ошибок, и предметная область такая, что неподготовленный человек не справится. И вообще — чужая самоуверенность в собственных силах не всегда в самом деле отвечает действительному уровню имеющейся квалификации, которая какая–бы она ни была — всегда есть своя собственная ошибка выжившего.
И друг и коллега, что задержался в проекте, откуда меня поперли, с мест событий передает информацию, что в Багдаде все спокойно, и все в–грудь–пяткой–пинатели на словах оказываются совсем не Львами Толстыми, способными легко выходить за привычные им рамки, в которых учились думать и преуспевать, не сталкиваясь с чем–то за пределами своих возможностей. Предпочитая стабильность приключениям. И снова никто не хочет думать.
Я в этом плане вполне допускаю, что есть еще более крутые код–мастеры, которые глядя на мои экзерсисы как могут и пальцем ткнуть в очевидный баг, которого я на пустом месте не видел, так могут тем же пальцем у виска покрутить, и сказать мол зря заморачиваешься, и тот же битрикс уже давно эту проблему решает. Пусть и не так элегантно.
А мне надо, чтобы именно элегантно! Иначе не считается, иначе не красиво. И там еще столького не хватает! И тоже чтобы обязательно красиво. А там еще есть вероятность, что что–то пойдет не так, как это бывало уже не раз. И надо будет снова включать голову, которая и так работает постоянно, анализируя то, что сделано, и то чем могу в полной мере управлять.
А вы так не можете! Бе–бе–бе! Вот сделали вам готовый класс, вот теперь с ним и ебитесь как умеете. Со всеми вытекающими из головы мозгами и ощущением чувства огромных собственных сил и великого ума, что смог справиться с такой большой и важной задачей, которая так сложно решается в этих несовместимых для простой жизни условиях!
А там и магия зеркальных нейронов подключается, и прочие коллективные подкрепления собственного превозмогания и достижения лучшего из результатов, в которых никого уже и не переубедишь, что это надо было и решать–то по другому. Так и проще получилось бы, и надежнее. Но там для этого подумать надо было не так, а здесь так не принято. И нет на это решительно никакой возможности. Мол, и рад бы по другому обращаться, да вот нельзя. В этой версии пока невозможно, ждем обновления. И там еще главное, чтобы зависимости не наебнулись. А то потом такое поле ошибок исправлять придется, ни одна психика не выдержит! А кто выдержит, тот еще сильнее в своих способностях к превозмоганию утвердится, и будет в этом бесконечно прав.
Выдыхай, бобер! Мантру запевай! Аом! Ты в нём и он в тебе самом: aom.
Но вообще я немного отвлекся. Пост изначально предполагался про уверенность и неуверенность в себе, а получился про фреймворки и чувство собственной важности от обретения навыков превозмогания проблем, которые сами себе выбрали превозмогать. И никто у нас этого не отнимет.
Что же, видимо про уверенность будет написано в другой раз. Тем более, что в существующих нормативах я уже приближаюсь к верхнему порогу, за которым пора останавливаться, ставить точку и идти отдыхать. Продуктивный труд требует продуктивного отдыха, и соответствующей физической активности.
А я недавно понял, как именно называется моя специализация, с точки зрения которой я подхожу к решению задач по программированию — дебаггер. Обнаружитель и устранитель багов. Я когда еще во ВНИИНС работал заслуженно назывался местным проктологом, за то что влезал в самые кущи, и обнаруживал там что–то давно забытое, но к чему все привыкли или обходили стороной, предпочитая решать новые задачи и вызовы, избегая старого геморроя, с которым все уже давно смирились. Кроме меня, которого это не устраивало, и который вызывался решать эти задачи за свой счет и под свою персональную ответственность, раз за разом давая качественный результат.
Причем, что характерно, на любом из фреймворков, с которым я сталкивался, на любом из языков, с которым я осваивался за считанные дни, не находя в этом ничего сложного.
В общем, за конкурентное преимущество в своем собственном направлении, куда рою собственный туннель, копая его крышкой своего ноутбука, я в целом и общем спокоен, и понимаю, что двигаюсь куда надо с нужной мне скоростью. И возможности развития и обобщения полученных решений с популярными технологиями я вижу, и картинка эта выглядит весьма оптимистичной и даже подбадривающей. Что, мол, это даже можно завершить в одно лицо, и сорвать все лавры. На которые всем, конечно же, будет глубоко похуй, и поддержка уже написанного количества кода в миллионы человеко–часов никуда не денется, и люди будут и дальше вынужденно думать в тех правилах, в которых их загнала эволюция человеческого мышления.
И вот мы здесь. А у меня еще юнит–тесты и не начинались даже. Но свет в конце тоннеля все виднее, и до всех самых благих намерений обязательно дойдут все мысли и действия, и каким будет результат зависит исключительно от собственной уверенности в правильности собственных действий и персональной ошибкой выжившего, который не видел ничего другого подобного, потому что и не смотрел в эту сторону. А меж тем какой–нибудь битрикс или, прости господи, 1С это давно уже успешно решают, а я тут всё самого умного из себя строю. Которому обязательно надо, чтобы было красиво!
Найди нормальную работу!
Полагаю, на этой ноте, дорогой дневничок, я и буду ставить точку в этом повествовании. И когда–нибудь обязательно что–то расскажу на эту тему еще.
Написал ॐ scarych на dd.d3.ru / комментировать