«Матрицу», я думаю, помнят все. А геймеры-старожилы могут помнить игру Sin. Там в какой-то момент главгерой садится за компьютер, а там почти что один в один реализован DOS — даже можно какую-то игру запустить.
Снится мне со вчера на сегодня, что я погружён в Матрицу (о чём я во сне знаю). Внутри Матрицы сажусь за компьютер, запускаю на нём Sin, дохожу до уровня с компьютером и запускаю ту самую игру.
Рекурсия то ли третьего, то ли четвёртого порядка — не знаю, считать ли сам сон за отдельный уровень вложенности. А вы говорите, «Начало»…
Отрисовываю на бумаге окончательную версию схемы к техзаданию сайта. Фоном идёт фильм о том, как японцы отправили ковчег (одноимённый с их флагманом времён Второй мировой) в космос. Уже минут десять не смотрю на экран, только слушаю, но мыслями там, в космосе. Идёт эпизод с последней сессией связи с кораблем. Голосовой запрос:
— Введите свой личный номер!
Отвлекаюсь на экран, вижу открытое открытое окно асимметрично-ушастой VoIP-говорилки с очередной «улучшенной функцией» (это цитата) — окном ленты Мордокниги.
Первое, что промелькнуло в голове: «А что писать-то?» Потом вспомнил, где нахожусь, и успокоился.
Пишу проект на Delphi. В работе использую нестандартные компоненты из набора AlphaControls. Есть там такой симпатичный TFramebar — панель со сворачивающимися вкладками, на которых размещаются фреймы. И удобно, и красиво.
И было бы всё тихо-мирно, не понадобись мне воплотить следующую идею. Есть два фрейма, реализующих пользовательские интерфейсы для поиска и сортировки в БД. Эти фреймы помещаются на вкладки упомянутого фреймбара. Получается очень кошерная менюшка для манипуляции данными. А в приложении несколько таблиц, и каждой такую менюшку нужно прикрутить. Как это сделать? Ну конечно — кинуть саму менюшку на новый фрейм и разместить его экземпляры везде, где понадобится. Получится фрейм, на котором находится контейнер фреймов, в котором лежит два других фрейма (фрейм на фрейме и фреймом погоняет), но выглядит идея здраво. Начинаю воплощать.
Оказалось, что фреймы на фреймбарe нельзя просто взять и разместить (как, например, на привычном TPageControl — накидал, и готово). Здесь у каждой панельки прописывается событие OnFrameCreate, в котором нужно указать тип создаваемого фрейма. Только в runtime экземпляр будет создан и размещён на вкладке.
И вот тут-то подкрался капец. Привычный механизм наследования, когда потомок имеет доступ к свойствам и методам предка, у этого компонента почему-то сбойнул. То есть экземпляры моего фреймоконтейнера понятия не имели, что где-то там, в родительском модуле, у TFramebar прописаны обработчики и типы для фреймов на вкладках. При запуске я лицезрел пустые панельки с надписью: «Frame creation event has not been defined».
Когда гугление, медитация и маты не помогли, в дело вступил метод научного тыка. Я попробовал создать обработчик уже для экземпляра фрейма-контейнера. Он создался, при этом обязательный в таких случаях вызов соответствующей процедуры из родительского класса в нём не прописался, что подтвердило предположение о том, что этот потомок своих предков не помнит. Попробовал прописать вызов вручную — куда там, не знает оно о его существовании. Ладно, тупо скопировал код из родительского обработчика — при запуске словил невнятный эксепшн. Убрал обработчик — снова «has not been defined». Плюнул, создал событие обратно, поставил внутри комментарий (чтобы Delphi не удаляла пустой обработчик) и запустил. Моё долгожданное меню сортировки смотрело на меня со вкладки контейнера.
Я не поверил. Повторил все пройденные пункты — та же фигня. Создал пустой обработчик с одним только комментарием внутри для второй вкладки — менюшка поиска встала в строй. Минут пять я медитировал на это дело. Потом вздохнул — и пошёл лепить эти костыли во всех экземплярах контейнера.
Теперь в нескольких модулях красуются потрясающие по глубине и содержанию фрагменты вида:
{ powered by magic }
procedure TfrQuoteView.sfrmbrDBmenuItems0CreateFrame(Sender: TObject; var Frame: TCustomFrame); begin // end;
procedure TfrQuoteView.sfrmbrDBmenuItems0FrameDestroy(Sender: TObject; var Frame: TCustomFrame; var CanDestroy: Boolean); begin // end;
И такая пара для каждой вкладки контейнера.
Не раз уже сталкивался, казалось бы, с мистическими глюками в работе, но причина всё же находилась. А здесь — увы… Powered by magic, в общем.
Не интереса ради, а работы для нужно было поставить скрипт багтрекера, написанного в нашей конторе. Проблема была: не хотел он заводиться. Пришлось ковырять движок.
Видно, что код не быдлокодер писал: красиво, с чувством, толком, интонацией и документацией. Только со странностями небольшими. Автор, видимо, очень любил покурить или покушать чего весёлого. Так, например, обнаружились стандартные настройки идентификатора статьи, который был объявлен так:
«Я ничего не трогал(а), оно само сломалось!» — сколько раз опытному админу приходилось слышать подобное от пользователей! На подсознательном уровне у нас выработалась привычка этому не верить, но…
Как-то утром, занимаясь любимым делом (вёрсткой своего сайта, а не тем, о чём вы подумали), я редактировал простейший HTML-код в наипростейшем Блокноте. Параллельно было открыто только одно окно Файрфокса с адресом страницы, исходники которой я и просматривал. Я не прикасался ни к мыши, ни к клавиатуре, находясь исключительно в визуальном контакте с компьютером. Чёрт меня дёрнул отвлечься от экрана — и в ту же секунду меня уже приветствовал Winlock, причём на немецком языке! Из текста я смог разобрать только фразу про детскую порнографию и просьбу перевести 100 евро и получить код.
Поскольку лишней сотни буржуйских денег у меня не было, пришлось идти альтернативным путём. Я нашёл хулигана вручную (ни один из существующих антивирусов на тот момент не определял заразу) и почистил реестр.
До сих пор я понятия не имею, как вирус попал на мой компьютер. Я ничего не трогал, оно само сломалось!
Лето. Отдых. Дача. Но какой отдых без интернета? Сестра отдала мне свой ноутбук, так как мой совершенно непонятным образом умер. Сказала, что он очень сильно тормозит и вообще «очень глючный». Удаляя ненужные программы, я наткнулся на странную утилиту Acer GraviSense. Удалять не стал только из-за первого слова — и хорошо, что не удалил!
Интернет на ноутбуке предоставлял USB-модем. Иногда по непонятным причинам передача данных прекращалась, и приходилось долго ждать, пока интернет снова не заработает. Во время очередного ожидания я случайно чуть не уронил ноутбук и успел увидеть поочерёдно вылетающие из трея надписи:
Shock or vibration detected, HDD protected. No shock or vibration, HDD is functional.
Необъяснимо, но интернет сразу же заработал.
Как-то заехала на дачу сестра. Естественно, сразу попросила интернет. Дал ей ноутбук, включил модем и ушёл по своим делам. Через некоторое время слышу:
— Что-то у меня перестали страницы грузиться. Помоги!
С серьёзным лицом захожу в комнату к сестре, беру ноутбук, трясу его несколько секунд, кладу на место, обновляю страницу — всё работает. Жалко, что никто, кроме меня, не видел лицо сестрёнки.
Как-то делали ремонт в серверной (промаркировать, освободить помещение, проконтролировать работу рабочих, собрать всё в причёсанном виде по фэн-шую). Запланировали на 3–9 января: оплата по двойному тарифу, а потом в оплачиваемый отпуск — убедили. 3-го разбираем, 8–9-го собираем, 4–7-го работают строители. Отпуск должен был начаться после фактического восстановления работоспособности сети — число не уточнялось, ведь «ничто и никогда не получается с первого раза».
Пришли пьяные, поработали, отрыли заначку шампанского, ещё поработали — разобрали. Рабочим оставили чёткие (по возможности) указания и ещё одну заначку шампанского. Рабочих не контролировали. Пришли 8-го пьяные, за день собрали, отрыли заначку рабочих. 9-го хотели подключить на трезвую голову — обмыли завершение. 10-го тестируем сами — нет проблем. С 11-го начинают выходить сотрудники — нет проблем. Мы хотим в отпуск. Начальство не отпускает: «Ничто и никогда не получается с первого раза!» Более тысячи концов СКС — выявленных косяков нет…
Пришлось рубить и восстанавливать один из не очень важных линков, после чего с чистой совестью валить в отпуск.
Место действия: уже упоминавшийся здесь исследовательский центр IBM в Хайфе, Израиль. Время действия: начало рабочей недели, девять утра.
Коллега по кабинету приходит на работу после хороших выходных. Долго ищет на системнике кнопку включения. Находит, нажимает. Компьютер, видимо, тоже хорошо отметивший выходные, издаёт серию писков и загружаться отказывается.
Здесь следует внести некоторую ясность. Политика большинства крупных компаний — узкая специализация работников. То есть программист, наваявший кучу кода для ядра сначала OS/2, а потом AIX, не имеет права лезть в засбоивший компьютер, потому что это прерогатива персонала технического обеспечения лаборатории. Такой подход вполне понятен, потому что для замены сдохшего устройства всё равно потребуется звать техника с запчастью. Получается, незачем разрешать программисту открывать свою шайтан-машину и лезть внутрь своими хоть и прямыми, но не заточенными для обращения с железом ручонками. (Да если даже заточенными — кто может поручиться, что точилка была правильной и фирменной?)
Прослушав последовательность писков и узнав модель BIOS из экрана POST-теста моего (точно такого же) компьютера, мы с коллегой вызываем техника и жалуемся на сдохшую видеокарту. Спустя десять минут появляется техник. Под мышкой — несколько цветастых коробок, в том числе и с видеокартой; в руке — литровая чашка чая; по глазам видно, что не только коллега с компьютером хорошо провели выходные.
Чашка и груда коробок сваливаются на стол; техник достаёт пациента из-под стола, укладывает его набок, отточенными до автоматизма движениями снимает боковую крышку системного блока и рассматривает слот видеокарты. Слот выглядит вполне AGP-шным (на дворе 2004 год), поэтому техник, не поднимая глаз, нашаривает на столе коробку с соответствующей видеокартой и тянет её к себе.
Коробка сталкивает со стола клавиатуру. Клавиатура летит вниз, но её останавливает провод. Поскольку провод входит в клавиатуру у правого дальнего угла, её разворачивает в воздухе, и острый передний левый угол с силой бьёт в беззащитную материнку.
Техник отбрасывает коробку с видюхой, подхватывает клавиатуру, водружает её на стол и толкает от себя. Клавиатура наезжает на свёрнутый спиралью провод, тот пружинит, и клавиатура снова бросается вниз со стола. Материнка получает ещё один удар в то же самое место.
Техник поднимается с пола и делает шаг назад, держа в руках клавиатуру. Её провод цепляется за чашку, и литр восхитительного, горячего, сладкого, свежезаваренного чая широким веером орошает обнажённую материнку. Долю секунды спустя на неё обрушивается тяжёлая фарфоровая чашка.
Техник в попытке подхватить чашку выпускает из рук клавиатуру. Та, влекомая всё тем же злосчастным проводом, припечатывает материнку в третий раз, взметая в воздух фонтанчик коричневых брызг.
Компьютер хрипит залитым чаем кулером на радиаторе процессора — выключить питание перед началом лоботомии никто, естественно, не подумал.
Техник, в ужасе от картины тотального разрушения, отступает на шаг назад. Под его башмаком хрустит цветастая коробка видеокарты…
Как ни странно, жёсткий диск не пострадал. В дальнейшем мы с коллегой долго думали почему. Сошлись на том, что у техника руки кривые: всё сломал, а жёсткий диск не смог!