Currently viewing the category: "R&D"

Сделал у себя в бложике параграфы «как у Лебедева». Правда у него по хардкору, табличками, а я соорудил на спанах.

Сделано, естественно, по-французски, потому что я не знаю, как правильно. А именно так.

В плагинах появился небольшой php-файл с таким текстом:

Я добавил к CSS-таблице следующую:

И дописал в конце JavaScript-код:

После этого, все заработало.

Идея, в общем, понятна, и при необходимости метод может быть расширен для простановки параграфов в цитатах или списках. Меня устраивает в таком виде. Осталось только понять, как это все барахло (включая подсветку кода, которую я тоже встроил) будет транслироваться в ЖЖ и РСС, для чего я и пишу этот пост.

Вот, кстати, для примера, ссылка на 5 параграф этого поста. Можете зайти и посмотреть на то, как это выглядит (параграфы проставляются только для отдельных постов, не для лент).

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

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

Звучит она так:

Перегрузка оператора присваивания

Пусть есть класс

class Boo : public SuperBoo

{

Foo* fFoo1;

Foo* fFoo2;

}

Где Foo – мономорфный класс, а класс Boo владеет указателями fFoo1, fFoo2.

Задача: перегрузить оператор присваивания для класса Boo.

Начнем с первого — с мономорфного класса. Все знают, что ООП состоит из полиморфизма, инкапсуляции и наследования. Определение полиморфизма можно прочитать в википедии, а пользуясь нехитрой логикой можно понять, что мономорфный — антоним понятия «полиморфный». Таким образом, в нашем случае, мономорфный класс — это класс, указатель на который всегда представляет его самого, а не его наследника.

То есть мы можем гарантировать то, что за Foo* скрывается класс Foo, а не какой-нибудь class MegaFoo : public Foo.

Второй вывод, который мы можем сделать из текста задачи — что класс Boo владеет указателями, а значит удаляет их в деструкторе. Таким образом, нам необходимо помнить о политике владения при написании оператора присваивания и четко удалять и создавать новые объекты.

Третий вывод позволяет нам сделать наличие суперкласса у Foo. Вполне возможно, что у SuperFoo есть оператор присвания, а значит нам необходимо его вызвать. Если же его нет — не беда, всегда есть оператор присваивания по умолчанию, просто копирующий блок памяти.

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

  1. Вспомнить синтаксис оператора присваивания
  2. Удалить fFoo1 и fFoo2
  3. Вызвать родительский оператор присваивания
  4. Сделать копии fFoo1 и fFoo2 у правой части оператора
  5. Вернуть ссылку на себя

В коде это будет выглядеть следующим образом:

Boo& operator=(const Boo& other)
{

delete this->fFoo1;

this->fFoo1 = nullptr;

delete this->fFoo2;

this->fFoo2 = nullptr;

SuperBoo::operator=(other);

if(other.fFoo1)

this->fFoo1 = new Foo(*other.fFoo1);

if(other.fFoo2)

this->fFoo2 = new Foo(*other.fFoo2);

return *this;

}

Это я и выслал в ответ на «тестовое задание», на что мне было сказано, что с заданием я не справился.

До сих пор гадаю, где же ошибка? На ум, конечно, приходит консистентность данных, защита от сбоев при выделении памяти и прочие кошерные вещи, но тут уже мой разум пасует — не настолько хорошо я знаю С++.

throw new YouWannaSomethingStrangeException();

Написал небольшую статью на Хабре, посвященную милым странностям синтаксиса и семантики C#.

Недавно на Хабре проскакивала статья, в которой человек описывал способы реализаиции своей «хотелки». Суть хотелки довольно путана описана в первоисточнике, поэтому я не буду ее дублировать, отсылая к оригинальной заметке, а от себя замечу, что по сути задача сводится к реализации примесей (mixins) в C#.

Конечно, решение автора не поражает изяществом. Давайте рассмотрим его проблемы несколько подробнее.

  • Интерфейс-метка IImplementor не имеет никакого семантического смысла, единственная его задача — это создавать иллюзию строгой типизации. Если мы его снимем — мы увидим то, чем он на самом деле является — голым object.
  • Необходимость сохранять функциональную связь между классами ведет к тому, что используются статические переменные, которые скрывают переменные классов-родителей. Особенно хорошо это видно в случае, если скомпилировать код — компилятор выдаст соответствующее предупреждение. Следует использовать метку new перед скрываемым полем, чтобы явно показать всю низость наших намерений.
  • Неоправданно много дублирования кода. В каждом без исключения объекте необходимо заводить статическое поле и переопределять виртуальную функцию получателя. Если по ошибке забыть это сделать — получим undefined behaviour на уровне системы, и найти ошибку в этом случае будет затруднительно.
  • Объект бизнес-логики (по постановке) обязан знать о возможности своего расширения «левым кодом», что явно нарушает SRP.
  • Необходимость сознательно соблюдать последовательность вызовоа метода — передавать в него тот же объект, от которого был запрошен исполнитель. Это очень легко нарушить непренамерено.

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

Читать статью полностью →

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

Читать статью полностью →

Многие отечественные сайты предпочитают отдавать ответы именно в этой кодировке. Нативной поддержки в Windows Phone 7 1251 страницы нет. Приходится изворачиваться.

Без этой страницы нет никакой возможности декодировать подстановки вида &x< код_символа>;. Поэтому без нее – как без рук.

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

Также, внутри вы найдете функцию для перевода кода в символ в заданной кодовой странице. Удивительно, но такой простой вещи в .NET не существует.

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

Читать статью полностью →

Внезапно, я понял, чего мне не хватает в жизни – легковесного почтового клиента.

Так получилось, что я всю жизнь пользовался Аутлуком, еще начиная с 2000-й версии. И он меня устраивал. И сейчас устраивает. Но дело в том, что почта для меня – не более, чем набор оповещалок с разных сайтов и тормознутая аська. Больше смысла в ней нет практически никакого.

Именно поэтому, я решил сделать для себя красивый и легкий IMAP-клиент, который бы клеился к моему почтовому ящику на gmail и снабжал меня всем необходимым.

Нередко возникает необходимость передавать собственные структуры в NSArray и аналогичных коллекциях, которые принимают в качестве элемента тип id.

Естественно, сделать этого напрямую нельзя, так как структуры языка С несовместимы с типом id, но это довольно просто обойти. Для этого следует воспользоваться типом NSValue.

Тип NSValue хорош тем, что в него можно положить произвольную структуру и достать ее оттуда, причем этот тип поддерживает типобезопасность за нас.

Допустим, у нас есть структура

С помощью категории, расширим класс NSValue парой методов

Тепреь можно работать с этими объектами в принятой в Objective C стилистике и не бояться за типобезопасность.

Как известно, в Objective C управлять видимостью методов, в отличие от видимости переменных, нельзя – все методы являются публичными. Насколько я понимаю, такое поведение имеет корни в модели “отправки сообщений”, которая тянется из Smalltalk. Любой объект отвечает на любое сообщение, которое он способен распознать и обработать. Технически, вызов метода представляет собой вызов функции objc_msgSend, принимающей указатель на объект, селектор и дополнительные параметры метода, и нет никакой возможности для среды выполнения определить, в каком контексте находится метод, кроме затратных, вроде передвижения по стеку и анализа лежащего в регистре self.

Ладно, нет так нет, нам от технической возможности или невозможности особо ни горячо ни холодно. Но ведь хочется! Хочется сделать нормальную инкапсуляцию, выстраивая грамотные иерархии наследования для исключения дублирования и возможности расширения, и чтобы не было соблазна ползать по внутренним методам, дергая за кишочки объектов. Ведь все ошибки в программах – это вина исключительно программистов.

Да, областей видимости действительно нет, но их можно имитировать, и я хочу показать, как.

Читать статью полностью →

PageLines