Кое-что о программировании

Этот пост частично основан на документе, который я оставил в «Интерфаксе» как рекомендации по сопровождению и развитию проекта «Раскрытие» перед своим уходом оттуда (кстати, на тему ухода из «Интерфакса» будет отдельный пост). Приведённые ниже подходы и принципы не претендуют на истину в последней инстанции, но за время моей работы неплохо зарекомендовали себя, поэтому я намерен продолжать пользоваться ими сам и, вот, с читателями тоже решил поделиться. Они являются продолжением принципа «в корпоративной разработке главное – поддерживаемость кода», и описывают приемы, которые можно использовать для увеличения очевидности кода (и, как следствие, его читабельности)→

Entity Framework, RAISEERROR, Microsoft и все-все-все

Столкнулся на днях с очаровательным багом в Entity Framework: при работе с некоторыми хранимыми процедурами EF не выбрасывает исключение при срабатывании внутри хранимки T-SQL инструкции RAISERROR. Microsoft не может вопроизвести проблему и поэтому отмахивается от неё, поэтому пришлось вооружиться отладчиком, напильником и такой-то матерью, резко выдохнуть и самостоятельно докопаться до истины→

Коллекция граблей

Наткнувшись сегодня в статье Александра Галкина «Немного об интерфейсах в .Net (по мотивам одного интервью)» на тот факт, что массив в .NET, оказывается, реализует многие члены интерфейса IList выбрасыванием NotSupportedException, я крайне удивился. Удивился, потому что привык, что .NET страхует программиста, не давая ему наступать на грабли, но в данном случае грабли лежат в основе основ фреймворка, в наисистемнейшем классе System.Array.  В чём же грабли, если эта недореализация недоступна в публичной области видимости? В возможности неявного приведения без каких-нибудь предупреждений.

Объявляет, к примеру, какой-нибудь программист интерфейс:

interface I
{
    void Test(IList collection);
}

Имеет, в общем-то, право.

Далее, какой-нибудь другой программист (ну, или тот же, неважно) реализует этот интерфейс:

class C : I
{
    public void Test(IList collection)
    {
        collection.Clear();
        // разные другие манипуляции
    }
}

И тоже имеет на это полное право.

Но потом приходит третий программист (ну, или тот же самый, но спустя пару месяцев), и пытается использовать этот интерфейс:

    C c = new C();
    c.Test(new[] { 1, 2, 3 });

И… получает NotSupportedException без объявления войны.
Особенно грустно становится, если вспомнить о том, что некоторые разработчики питают нездоровое пристрастие к неявной типизации (впрочем, про неё лучше отдельно как-нибудь), что чревато подобными участками кода:

    var integers = SomeFarObject.GetSomeCollectionOfIntegers(); // int[] GetSomeCollectionOfIntegers()…
    c.Test(integers);

Ой. А стукнет по лбу уже в рантайме — эксепшен вылетит прямо в лицо тестировщику (хорошо, если не клиенту). Неприятно.
Кто-нибудь в курсе, зачем System.Array реализует IList, с какой целью?

Настройка IPv6 на CentOS 6

Уже довольно давно Хетцнер (англ.) раздаёт IPv6-подсети для каждого дедика, что весьма приятно. Ну, попробуем воспользоваться.
Для CentOS 5 всё отлично расписал в своё время Павел Одинцов, но для CentOS 6 есть один маленький нюанс.
Что ж, делаем как написано:
Добавляем NETWORKING_IPV6=yes в /etc/sysconfig/network (это включит системную поддержку IPv6)
Конфигурируем сетевку: добавляем /etc/sysconfig/network-scripts/ifcfg-eth0 IPV6INIT=yes и IPV6ADDR=2a01:4f8:162:54c3::2 (подобно Павлу возьму ::2 в качестве основного адреса)
Настраиваем маршрутизацию: создаём /etc/sysconfig/network-scripts/route6-eth0 и прописываем в него: fe80::1 dev eth0 и
default via fe80::1 dev eth0 (где fe80::1 — шлюз по умолчанию)
В этом и заключается нюанс: интерфейс следует указать явно, иначе работать не будет:
# ip -6 route add fe80::1 dev eth0
# ip -6 route add default via fe80::1
RTNETLINK answers: Invalid argument

Спасибо неизвестному сисадмину, который не поленился запостить решение проблемы в созданный им тред (англ.) после того, как сам разобрался с ней.

Используя using

Один из моих самых любимых вопросов на собеседовании: в чём опасность такой конструкции?

…
using (MyClass myClass = new MyClass() { Prop = p })
{
    myClass.Use();
}

Выглядит вполне невинно — до тех пор, пока не начинаешь задумываться в том, как это устроено внутри→

О литералах, регулярных выражениях и пользе документации

Один из моих коллег недавно наступил на грабли, словив глюк с неочевидными на первый взгляд симптомами, которые и сформулировать-то затруднительно. В общем, дело было так: сидит он себе, никого не трогает, программу пишет. Конкретно — фильтр, пропускающий лишь символы из определенного диапазона. Достаточно широкого, кстати: по сути, требовались отсечь управляющие символы, за исключением некоторых (отдельно хочу отметить сам подход: отсечь всё, кроме нужного, а не отсечь ненужное — это правильно; почему-то разница очевидна не для всех). Читать далее

Чем лучше я узнаю PHP, тем больше я люблю C#. Издание второе, переработанное и дополненное.

Когда-то давно (но уже после того, как я принял решение стать дотнетчиком) я случайно наткнулся на хабре на перевод статьи «PHP: a fractal of bad design», и лишь тогда осознал всю глубину той бездны, из которой намеревался выбраться. Пока я работал с PHP, мне каким-то образом (чудом, не иначе) удавалось избежать большего количества мин и граблей. Но недавно мне довелось ещё раз убедиться, что я принял верное решение.

Читать далее