воскресенье, 31 января 2010 г.

Начинаем все сначала?

Блог в своем первом варианте не пошел :)
Одна из основных причин это отсутствие четкой направленности его тематики. Думая пол года назад об этом я хотел его реанимировать и начать писать что нибудь по околорабочей области (платежные системы, сервисы и прочее), но ничего не получилось, скажем так - из черновиков не вышел ни один пост :) Кроме всего прочего последнее время мной в большей степени охватил микроблогинг twitter (если кто не знает @tagirovarthur это я ;)
Быть может когда то, я открою отдельный тематический блог... но он явно будет иметь другое название (если внезапно есть предложения - пишите, я рассмотрю :)
Ну а пока решил писать тут просто некоторые веселые и не очень моменты из своей жизни, все таки блог имени меня ;)
P.S. В целях исследования открою "зеркало" на spaces от live.

Гребени 2010-01-31

Сегодня меня таки вытащили покататься на сноуборде! Всего в жизни катался на нем 2 раза, сегодня был как раз второй :)
Погода сегодня была хорошая, не то что весь последний месяц, всего то -10 и практически никакого ветра. Как выяснилось по прибытии, кататься я разучился, пришлось учиться заново... теперь через год снова поеду учиться кататься на сноуборде ;)
Из полезностей от меня - заснял нашу главную лыжницу на видео, ну хоть какая то польза человеку. После катания с трудом доковылял до дома, теперь отлеживаюсь вот... надеюсь ходить завтра я смогу и дойду таки до работы :)
Ниже маленький фото отчет с места:
P.S. И напоследок, спасибо тем, кто меня вытащил, снабдил сноубордом и даже не угробил :)

суббота, 19 апреля 2008 г.

+++


IMG_0452
Originally uploaded by arthurtagirov
Ну вот, наконец то, и я открыл сезон катания на велосипеде :) После небольшой игры в футбол, подцепился на хвост к другу и затем мы немного покатались по зауралке и не только... Естественно, теперь у меня все болит, но я доволен :)
P.S. По-моему, это первая фотография с моего фотоаппарата со мной за этот год :)

пятница, 21 марта 2008 г.

Blog.ru

Сегодня наткнулся на блог - blog.ru. Первым делом меня очень развеселила надпись на главной странице - "Твой блог на blog.ru. Логично?". А что, и вправду логично :) В общем, я решил его попробовать, к тому же там была обещана некая интеграция с lastfm.
Честно признаюсь, как дело обстоит с lastfm я еще не посмотрел, но вот что мне понравилось, так это возможность импорта записей из других систем, в частности с blogger. Все мои записи спокойно перенеслись в blog.ru, что самое главное вместе с тегами. Конечно для этого надо было указать логин и пароль, но если кто то не доверяет системе (я то наивный чукотский парень), то может воспользоваться импортом сообщений из RSS (Atom так же поддерживается, на сколько я понял) ленты (не знаю как там с тегами, но по моему их в таком случае просто неоткуда брать). В импорте есть настройки, какие имено посты необходимо импортировать - это могут быть все посты (которые уже есть и которые будут поялвяться в блоге), только вновь появляющиеся и только те, которые уже есть.
Вообще, настроить можно несколько источников в ваш блог, и в данном случае поддержка RSS - это очень хорошо ;) Правда вот относительно лент появляется вопрос - как проверить что это ваша лента, но оставим этот вопрос на потом.
Так же можно настроить постинг постов через email, что может быть очень удобно для микроблогинга.
Возможностей по настройке интерфейса и прочему наблюдается не так много, но я пока не настолько сильно во всем разбирался. Честно признаться - этот пост является неким тестовым постом, который по идеи должен со временем автоматически появиться и в blog.ru. Так что - скоро напишу более подробный экскурс по этому новому для меня блогу.
P.S. Кстати говоря, есть еще и экспорт блога, который я быть может тоже скоро попробую ;)

воскресенье, 9 декабря 2007 г.

Отмучался с Emit...

В предыдущем посте я описывал свой механизм проектирования по контракту. Никто ничего не откомментировал по его поводу, ну да ладно, не будем сейчас про это. Сегодня я закончил еще один этап своей работы, а именно генерирование прокси класса по определенному интерфейсу, который внутри себя использует класс ContractsManager, который в свое время внутри себя использует класс, который реализует необходимый интерфейс - ужас одним словом ;)
Попутно с этим, мне пришлось немного разобраться с таким пространством имен как System.Reflection.Emit. Страшное, надо сказать пространство имен ;)
С генерированием конструктора, который принимает параметр и запихивает его в специальное поле, проблем не возникло - примеров этого было много :) Ну попутно еще разобрался с тем, как сгенерировать поле.
Дальше началась проблема - необходимо было сделать метод, который реализует метод интерфейса следующим образом: внутри себя вызывает специальный метод у поля. Этому методу надо было передать имя метода и параметры метода. Ну так приблизительно я и сделал... Но прокси класс никак не хотел работать, со словами, что у него там какая то фигня сгенерирована, а не метод интерфейса :) Через некоторое время до меня наконец дошло, что это в C# ключевое слово params позволяет перечислять параметры через запятую... но потом они упаковываются в массив, а следовательно надо передавать не параметры, а массив параметров... И тут встала проблема - как создать локальную переменную в виде массива объектов, заполнить этот массив из параметров и передать куда нибудь... К счастью google помог и в этом :)
В итоге могу сказать - даже если плохо разбираешься в системном программировании .NET (имеется ввиду Emit, да и вообще программирование на чистом MSIL), то google лучший помошник. Хотя информацию приходиться агрегировать из примеров по маленьким кусочкам... Кстати говоря, ни нашел ни одного нормального источника на русском (да и английском), где можно было бы подробно почитать про Emit. Есть что то на intuit, но там на очень конкретном примере, в котором многое опускается...
P.S. А еще наконец то заменил себе старый монитор на новый ;)

воскресенье, 2 декабря 2007 г.

Проектирование по контракту - первые попытки

Сегодня я предложу вам один способ использования проектирования по контракту в .NET, точнее очередную библиотеку, автором которой и являюсь ;) Надеюсь, что вы напишите свои впечатления, замечания, пожелания и т.д. и т.п.
На сегодня, наверное, будет только один пример использования. Пример, который используется во многих статьях про проектирование по контракту - класс стек ;)
Сначала приведу код интерфейса - он довольно простой ;)
public interface IStack<T>
{
int Count { get; }

bool Empty { get; }

void Put(T item);

T
Remove();

T
GetItem();
}
Теперь можно сказать, какие предусловия, постусловия и инварианты можно придумать для данного интерфейса. Инвариантом может послужить условие о том, что количество элементов всегда больше или равно нулю. Предусловием для методов Remove и GetItem будет то, что количество элементов в стеке больше нуля. Постусловием для метода Put будет то, что свойство Count увеличивается на единицу, для Remove - уменьшается на единицу, для GetItem - свойство Count не изменяется.
По схеме, которую хочу предложить вам я, все утверждения записываются в отдельном классе (хотя их может быть и больше). Для каждого метода этого отдельного класса можно указать чем именно он является - предусловием, постусловием или инвариантом. Так же, необходимо произвести что то вроде mapping`а или биндинга параметров этих методов к параметрам проверяемого метода, а так же свойствам и полям. Все это делается через атрибуты.
Приведу пример проверяющего класса:
internal class StackCheck
{
[Invariant("Количество элементов больше или равно 0")]
public bool CheckCount(int Count)
{
return Count >= 0;
}

[Ensure("Количество элементов увеличивается на единицу", "Put")]
public bool EnsurePut(
[Old][PropName("Count")] int oldCount,
[PropName("Count")] int count)
{
return count == oldCount + 1;
}

[Ensure("Количество элементов уменьшается на единицу", "Remove")]
public bool EnsureRemove(
[Old][PropName("Count")] int oldCount,
[PropName("Count")] int count)
{
return count == oldCount - 1;
}

[Ensure("Количество элементов не изменяется", "GetItem")]
public bool EnsureItem(
[Old][PropName("Count")] int oldCount,
[PropName("Count")] int count)
{
return count == oldCount;
}

[Require("Стек не должен быть пустым", "GetItem")]
[Require("Стек не должен быть пустым", "Remove")]
public bool RequireNotEmpty([PropName("Count")] int count)
{
return count > 0;
}
}
Несложно заметить, что все проверочные методы должны возвращать bool, в противном случае этот метод будет опущен при проверке.
Атрибут Invariant задает, что метод является инвариантом класса, в данном случае такой метод один - CheckCount. В параметр конструктора атрибута можно передать описание инварианта. В случае, если инвариант не выполнится, то это сообщение будет использоваться в качестве сообщения ошибки, так же этот текст может быть использован для документации (подумываю позже написать что нибудь и для этого ;).
Перед параметром Count этого проверочного метода нет никакого атрибута, в таком случае для метода инварианта этот параметр будет пытаться биндиться к свойству проверяемого класса с соответствующим именем (регистр в данном случае важен), если такого свойства не будет, то к полю с таким названием, если не будет и поля, то сгенерируется исключение. В общем случае перед параметром проверочного метода инварианта можно указать один из двух атрибутов - PropName (биндится к свойству с указанным именем) или FieldName (биндится к полю с указанным именем).
Следующий метод помечен атрибутом Ensure. Этот атрибут принимает два параметра: описание (использование аналогично инварианту), а так же название метода, к которому относится постусловие. Кроме уже имеющихся возможных атрибутов параметров, в постусловиях можно использовать атрибут Old. Он говорит о том, что значение свойства (или чего то другого, в зависимости от второго параметра) должно браться до того, как был вызван проверяемый метод. Так же, кроме атрибутов биндинга к свойству и полю можно использовать атрибут биндинга к параметру метода - PropName. Если никакого атрибута не проставлено, то считается, что стоит атрибут PropName с названием аналогичному названию параметра. Сам метод EnsurePut проверяет, что количество элементов после вызова метода Put в проверочном классе будет увеличено ровно на единицу. Следующий метод - EnsureRemove, практически идентичен предыдущему, только он проверяет, что количество элементов уменьшилось на единицу после вызова метода Remove. Далее идет метод EnsureItem - он проверяет, что после вызова метода GetItem количество элементов не изменится.
Следующий метод помечен атрибутом Require (даже двумя ;) Параметры атрибута Require аналогичны атрибуту Ensure, только он говорит о том, что помеченый им метод является предусловием, а не постусловием. К параметрам метода предусловия могут применены все те же атрибуты, что и к методам Ensure, за исключением Old (он просто опускается и не учитывается). Как видно из кода, здесь проверяется, что перед вызовом методов Remove и GetItem количество элементов больше нуля.
В принципе, логичнее проверять не свойство Count, а свойство Empty. В таком случае код можно переписать так:
[Require("Стек не должен быть пустым", "GetItem")]
[Require("Стек не должен быть пустым", "Remove")]
public bool RequireNotEmpty([PropName("Empty")] bool empty)
{
return !empty;
}
Как можно заметить, сам класс помечен как internal. По крайней мере для рефлексии это имеет не такое большое значение ;)
Теперь, имея такой класс, мы можем сказать интерфейсу стека, что он должен использовать его в качестве проверочного - для этого служит атрибут ContractsType, которому необходимо передать тип проверяемого класса. Еще одно немаловажное свойство, в связи с этим, проверочный класс (в нашем случае StackCheck) должен иметь пустой публичный конструктор (хотя по поводу публичного - кто знает эту рефлексию ;)
[ContractsType(typeof(StackCheck))]
public interface IStack;
{
//Описание интерфейса...
}
Наверное теперь у вас возникает вопрос - как все это использовать? А использовать все это можно через специальный класс, который называется ContractsManager - он создается для экземпляра определенного класса. Например можно использовать вот так:
Stack<int> stack = new Stack();
ContractsManager contractsManager = new ContractsManager(stack);
int res = contractsManager.RunMethod<int>("Remove");
В данном примере мы создаем класс "обертку", которая может вызвать метод вместе с проверками. Заметьте, что используется generic метод - для того, что бы указать, результат какого типа вернет метод. Так же, обратите внимание на то, что здесь используется класс Stack - наследник интерфейса IStack - т.е. все проверки наследуются по иерархии.
Т.к. стек создается по умолчанию пустой, то в данном случае сгенерируется исключение - RequireException с текстом сообщения - "Стек не должен быть пустым".
Если необходимо вызвать метод без каких либо проверок, то можно просто вызвать метод у экземпляра класса. Но это еще не все. На самом деле у каждого из атрибутов (Invariant, Require и Ensure) имеется еще один параметр, который можно задать - это приоритет (по умолчанию он равен 0). У класса ContractsManager в свое время так же есть 3 свойства которые задают максимальные приоритеты для инвариантов, предусловий и постусловий (по умолчанию тоже равны 0). Соотвественно эти свойства можно менять во время исполнения программы тем самым "балансируя" производительностью.
Естественно, что все это пока только... бета ;) Уже сейчас есть некоторые проблемы, например с generic - скажем так, пока что я особо не обращаю на них внимание. Так же, есть еще несколько идей относительно того, что можно было бы еще добавить. В общем, жду так же и ваших комментариев ;)
P.S. Да, я очень не хороший мальчик, но библиотеку с кодом всего этого я пока никуда не выложил ;)

Pipes

Наткнулся сегодня на один интересный сервис. Служит он для построения лент новостей из уже имеющихся, причем имеется очень много интересных возможностей.
Например можно взять обычную ленту новостей и отфильтровать все ее записи по категориям или еще чему нибудь. Так же можно переименовать часть полей, можно сделать join нескольких лент, ну и всякого рода другие интересные возможности. В общем, советую попробовать хотя бы ради интереса ;)
Из недостатков пока нашел только то, что иногда русский язык отображается неправильно (но скорее всего это связано с неправильным указанием кодировки в самой ленте новостей).
Сам сервис предоставляет yahoo, но самое интересное, что при этом сервис использует некоторые API от google. В общем, идея, конечно интересная, посмотрим что будет дальше.