понедельник, 23 апреля 2012 г.

Мысли о третьем шаге в TDD

Сегодня второй раз в жизни пишу код согласно чистому TDD, прямо как заповедали такие мастера, как Роберт Мартин, Эндрю Хант и Майкл Физерс. Один случай меня заставил серьёзно задуматься о разнице в подходах к разработке.

Третий шаг в TDD гласит: «напиши ровно столько кода, сколько нужно для того, чтобы проваливающийся ранее тест начал завершаться успешно». (Первые два это «напиши проваливающийся тест» и «заставь этот тест компилироваться»). Несмотря на то, что он кажется довольно простым, пункт насчёт «ровно столько, сколько нужно» невероятно важен в рамках этой методологии.

Этот пункт, среди прочего, означает, что, если твой тест не предусматривает обработку ошибочных данных — значит, тебе нельзя писать такую обработку в коде. Если твой тест только проверяет тип результата функции, но не корректность его значения — значит, тебе нельзя писать код, который генерирует реальные правильные данные.

Только после раздумья длиной что-то около полудня я понял, почему так важно соблюдать это правило, хотя ответ очень прост. Если ты напишешь код, который не предусматривают твои тесты, пусть даже он будет выполнять какую-то идейно полезную работу (а он, конечно же, будет выполнять идейно полезную работу), он не будет покрыт тестами. А код, который не покрыт тестами — это legacy код, которому положено гореть в аду. Более того, если ты оставишь весь этот код среди другого, чистого и покрытого тестами, он будет, как ржавая арматура, мешать добавлять новую функциональность. Так как он не покрыт тестами, а ты в целом стараешься следовать TDD, значит, все эти буквы становятся просто шумом, про полезность и надёжность которого ты не знаешь ничего.

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

четверг, 19 апреля 2012 г.

Подключение к Windows VPN серверу из Debian

О-хо-хо, как же я давно не писал!..

Есть важная особенность при настройке VPN соединения к Windows-серверу из Debian. Это если не считать того, что на самом деле это называется не VPN, а PPTP подключение, ну да простим Майкрософту эту мелочь.

При настройке подключения, следует указать, что разрешён только один метод аутентификации: MSCHAPv2. И включить MPPE шифрование. Спасибо orbnajes с форумов Fedora за объяснение.

Без этих действий VPN подключение будет молча обрываться, и сообщение об ошибке в syslog'е мало поможет.

update: Ещё, возможно, придётся уменьшить MTU на сетевой карте, или подключению будет очень дурно, и оно регулярно будет обрываться. Для того сервера, который мне был нужен, сработало уменьшение MTU с 1500 до 800.

понедельник, 23 января 2012 г.

Настройка отправки почты с локального Debian сервера через exim + gmail

Прикручивал некоторую функциональность на сайт, который развёрнут на моей локальной машине, и понадобилось проверить, в каком виде отправляются письма с сайта. А почтового сервера-то на моей машине и нету!

Воспользовавшись учёткой на гуглопочте и руководством в Debian Wiki, мне удалось всё настроить за ~5 минут, чего и вам желаю. Авторы руководства, большое вам человеческое спасибо.

Напомню, что в стандартной поставке Debian Squeeze (который уже я частично переделал на Wheezy) устанавливается MTA exim4, настроенный на исключительно локальную доставку почты.

четверг, 12 января 2012 г.

Видеодрайверы для Debian на Dell Inspiron N5110

После переезда на новый Dell Inspiron N5110 выяснилась неприятная новость: в нём установлены две видеокарты, работающие по технологии NVidia Optimus, и в Debian она официально не поддерживается. Все эти приятные вещи я узнал из поста на форуме убунтоводов насчёт NVidia Optimus.

Я отключил себе видеокарту NVidia, следуя рекомендациям robbyx.net (пункт #3), и буду следить за жизнью проекта Bumblebee, посвящённому реализации NVidia Optimus на Linux. Возможно, придётся даже включиться в разработку этого проекта, а то мне очень хочется быстрый OpenGL у себя на ноуте в Debian.

Программирование компьютерных игр в Common Lisp при помощи lispbuilder-sdl

Сегодня сбылась мечта идиота: нашёл пакет для графики в Common Lisp, с помощью которого можно рисовать игры с графикой и звуком. Это не GUI пакет с виджетами, это 2D/3D канва и инициализаторы для звука, джойстика и CDROM. Пакет называется lispbuilder-sdl, и он крут.

Как обычно, напомню для себя, как lispbuilder-sdl подключается в SBCL.

четверг, 5 января 2012 г.

Интернационализация MySQL 5.1

Сегодня меня вконец достала дефолтная настройка на latin1 в MySQL, и я пошёл курить маны. Хочется, естественно, перевести всё в utf8. Решается, как оказалось, всё тремя строчками в конфиге.

понедельник, 26 декабря 2011 г.

Фильтры в Битриксе

Сегодня, после года практики в Битриксе мне открылось поистине тайное знание.

Когда передаёшь в компонент имя переменной-фильтра через 'FILTER_NAME', Битрикс ожидает имя глобально доступной переменной. Там прямо в исходниках любого компонента можно увидеть вызов

global ${$arParams['FILTER_NAME']}
или, во всяком случае, аналог этого кода. А раз используется поиск переменной средствами ключевого слова global, то без шаманства можно забыть о таких интересных вещах, как динамическая генерация фильтра внутри объектов классов или вообще внутри любого lexical scope, отличающегося от глобального.

Сегодня же до меня дошёл смысл этого global. Фильтр надо просто сохранять как элемент массива $GLOBALS, вместе со всеми остальными глобальными переменными. Это, по-видимому, самый надёжный способ генерировать фильтр и передавать его имя в компонент.

Следующие две инструкции могут быть теперь вообще где угодно, как угодно глубоко внутри иерархии классов и/или стека вызовов:

$GLOBALS['similar_items'] = array(
 '=EXTERNAL_ID' => getSimilarItems($arResult)
);
$APPLICATION->IncludeComponent(
 "bitrix:catalog.section",
 "",
 Array(
...
  "FILTER_NAME" => 'similar_items',
...
 )
);

Я знаю, вы всегда мечтали хранить временные данные в глобальной области видимости, не правда ли?

Пиздец.