четверг, января 25, 2007

День под знаком "петли"

Сегодня у меня был ужасный день... На моей Тоше (Toshiba Satellite Pro M30) жутко расхлябалась левая петля :(. Такое случалось и раньше, но там я обходился малой кровью, а именно: снимал с петли накладку (снимается она легко) и под две скрепленные заклепкой пластины (между которыми и образовывался люфт) подкладывал всяческие железки. Это помогало, но на некоторое время. Я прекрасно понимал, что раз оно заболталось, значит с одной стороны у заклепки отваливается шляпка, но с какой было не ясно. Операцию подкладывания я проводил целых три раза, и вот сегодня свершилось... Люфт стал настолько большим, что при открывании крышки накладка петли сама-собой отщелкивалась :(. Ничего не оставалось делать, как разобрать бук и посмотреть на виновницу "торжества". Как я и предполагал, нижняя шляпка заклепки отвалилась наполовину. Пришлось вооружаться плоскогубцами и пилкой по металлу т.к. заклепка выниматься не желала. Получасовая битва наконец принесла свои плоды, заклепка сдалась! Я подыскал подходящий по размеру болтик с "гравером" и гаечкой и принялся восстанавливать работоспособность железного элемента. Наконец все закончено и бук можно собирать! Ура! Сборка прошла весьма успешно и я был уже готов включить его и проверить на "мало ли чего", как вдруг вспомнил, что не поставил накладку на петлю. Ну-да, дело плевое, не первый раз, решил я, и принялся накладку устанавливать. Но, не тут-то было... Гаечка оказалась слишком толстой, и накладка, ни как не хотела надеваться на петлю :(((( Щьёрт побьерьы!!! Снова разбирать бук... Это был сильный стресс... Но делать нечего, пришлось вновь разбирать до винтика (если кто разбирал эту модель, поймет, там снимать нужно все вплоть до HDD и CD). После разборки и поиска замены толстой гаечке, я обнаружил, что заменить ее нечем :((((( На помощь пришел напильник, коим я старательно обтачивал гайку, а заодно и головку болта. Покончив с этим делом, и примерив накладку (она наделась просто чудно) я решил, до кучи, еще и кулер смазать литолом! Надумано - наделано! Кулер смазан, накладка надета, осталась сборка. Сборка заняла минут пять, потом влажная уборка рабочего места и протирание матрицы и самого бука. У-ф-ф-ф... Зато теперь петля никуда от меня не денется ;)

вторник, января 23, 2007

Наследование записей

Ну не так, чтоб уж совсем наследование, но механизм расширения функционала рабочий. Итак: определяем запись TRecord с неким множеством методов. Затем (типа наследуемся) определяем запись TRecordDesc = Type TRecord. Теперь эти записи не совместимы (для чего это нужно - ниже). Описываем Record Helper For TRecordDesc с неким множеством методов/свойств. В итоге, мы получили функционально расширенную запись, ну а несовместимось нужна была, чтоб члены record helper'а не попали к предку. Однако копирование записи достигается простым приведением типа ;) Если бы хэлперы позволяли описывать перегрузку операторов, можно было обойтись и без приведения.

Однако есть еще способ ;). Можно использовать агрегацию, тем самым избавиться от хэлперов и приобрести возможность перегружать операторы :).

понедельник, января 22, 2007

Где, блин, революция!?

Еще, когда только планировалась к выходу Delphi 6, весь инет шумел о веб-сервисах, все говорили, что вот, грядет оно, светлое будущее. И собственно где? Ну блоги, понятное дело, ну еще г-н Орейли чего-то там сделал, ну да, г-н Виннер, а еще? Публичных веб-сервисов кот наплакал, да и те умеют лишь рапортовать о валюте, времени да погоде... Это я к чему, да просто г-н Балмер недавно снова предсказал революцию веб-сервисов в течении ближайших 10 лет :).

Что еще интересно, по задумке идеологов, веб-сервисы должна была объединить одна важная особенность - протокол взаимодействия (тогда на это точили SOAP, а Borland даже сделала RTTI для интерфейсов в шестой версии). И взгляните, что происходит сейчас: образовалась целая куча подходов к осуществлению взаимодействия (SOAP, XML-RPC, REST, JSON, PI-RPC, AJAX и.т.д), каждый считает себя самым умным и делает то, что считает нужным. Например контора на "Г" прибила бету поискового сервиса на SOAP, и перевела его на AJAX (чего уж не на GData).  Таже контора обещает отломать от Blogger'а XML-RPC API и перейти на что-то свое... Короче, разброд полнейший... Что-же касается SOAP, то он уже давно превратился в монстра с которым, никому, кроме породивших его Франкенштейнов, связываться не хочется.

воскресенье, января 14, 2007

Что делают в армии?

На этот вопрос каждый отвечает себе сам :) Я пошел в армию вполне осознанно, бросив учебу в университете. Пошел, потому что так было надо (ну воспитывали нас так), т.е. все нормальные косили, а остальные шли служить. До этого я учился в техническом лицее, где получил диплом программиста и к тому времени писал на Clipper'е, Turbo Pascal'е и Assembler'е. Имея первое место "на республике" по программированию, и соответствующий диплом, я наивно полагал, что в армии тоже буду программировать :) Но так в общем и вышло ;) Служил я в РВСН в/ч 44200, прикомандированным к центру психологической работы. Программировал в основном психологические тесты разных мастей по именитым методикам, но такая работа мне не очень нравилась, хотя и напрягала не особенно. Но кроме этого довелось мне писать две интересные программы: первая - расчет заработной платы военнослужащих, а вторая - мой дембельский аккорд (оптимальное распределение военнослужащих). О второй писать не буду т.к. писать придется слишком много :) Ну а первая, вот она:

 Написана на Borland Pascal 7.1 with objects. Работала под DOS, в режиме 640 x 480 x 4. В качестве базы данных использовался самописный движок для работы с .dbf (это была моя дипломная работа в лицее). Для программирования интерфейса импользовалась также самописная библиотека. Жаль, что в то время, я ни как не мог въехать в прелесть ООП и библиотека по сути состояла из объектов, но представленных весьма специфично ;) (т.е. каждый объект был записью которая манипулировалась неким множеством процедур и функций). Программа расчета  имела возможность создавать архивные копии данных при переходе на новый месяц, была предусмотрена система справочников, а для простоты изменения алгоритма расчета мне пришлось добавить поддержку формул, для чего был написан синтаксический анализатор (как же мне было трудно и интересно ;)) По интерфейсу было решено закосить под недавно вышедшую Windows 98, отсюда и название такое ;) Мне даже было не влом сделать поддержку цветовых схем аля Windows (см. следующий скриншот)

 

 

 

 

 

 

Программа получилась даже очень ничего ;) и была внедрена в одной из воинских частей, за что я был премирован новой шоколадной "афганкой" (кто служил тот поймет ;) Вот этим я занимался в армии :)

пятница, января 12, 2007

Ностальгия...

Сегодня наткнулся на скриншоты своей (ну писал-то я ее не один, нас было двое, но скрины только моего творчества ;)) первой и единственной корпоративной (как это модно сейчас называть) системы. Чего-то воспоминания нахлынули... В общем вот:

Это диалог регистрации пользователя в системе, где помимо обычных в этом деле  Диалог регистрацииполей можно было указать еще псевдоним базы данных к которой будет производится подключение. Это было очень удобно для разработки (а она непрерывно велась в процессе эксплуатации системы) т.к. все спорные моменты и приемы отлаживались на тестовой базе, а при опасных манипуляциях можно было подключиться и вовсе к резервному серверу :).

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

Процесс публикации отражен на следующем скрине:

Пример UI сервераЭто не боевой сервер, скрин был сделан специально для демонстрации состояний клиентских подключений. В динамике все выглядело очень эффектно :), при каждом новом запросе, мониторчик клиента мигал, было сказачно красиво ;).

Моим первым приложением был "Электронный табель" позволявший на местах (в цехах, на промыслах) вести электронный учет рабочего времени, что позволяло отделу кадров оперативно отслеживать ситуацию на рабочих местах и вносить соответствующие коррективы. Но скрина этого приложения у меня не сохранилось, вместо него публикую скрин приложения "Отдел труда и зарплаты",ОТиЗП которое полностью повторяло функционал ведения табеля, но кроме этого делало еще массу полезных вещей :). На этом скрине видно большое меню, которое формировалось  (т.е. выполнялся весьма приличный запрос к серверу и по результатам строилось меню) в момент клика пользователем на соответствующем пункте. Работало очень даже шустро :)

Затем было написано приложение "Банковские операции", но его скрина у меня тоже не сохранилось. После отработки по банкам, я сел за приложение "Кассовые операции", скрин которого приведен ниже.Кассовые операции Это было достаточно простое приложение, но в нем был один интересный (в то время) для меня момент: его нужно было интегрировать с веб-сервером разработчиков (т.е. не корпоративным, а именно девелоперским, т.е. нашим) т.к. на сервере работал скрипт завязаный на сторонний софт, и тащить тот софт на клиента не было ни какого желания (это только добавило бы головной боли). Почему именно веб? А почему нет! :)

Затем мне пришлось возвращаться к старой теме (дело в том, что ранее я уже писал для этой конторы сию прилагу, но только под ДОС, и по договору т.е. я там еще не работал) и писать приложение "Подотчет".Подотчет Изюминкой этой работы для меня стала реализация "мультиформенного" приложения т.е. приложения без главной формы (office2000 like). Решилась проблема достаточно просто и эффективно, правда пришлось сильно попотеть изучая механизмы взаимодействия различных частей VCL, чтоб обеспечить корректность работы в таком режиме. Особенно это касалось модальности окна только для активной формы.

Ну и наконец скрин боевого сервераБоевой сервер. На скрине открыт диалог настройки с назначением прав пользователя. Пользовательская база была интегрирована с базой MS-SQL на котором и крутилась вся система. На SQL сервере было всего 25 лицензий, но за счет серверной части нашей системы (т.е. по сути ее второго уровня) на этих лицензиях работало ~70 целовек :) (я делал стресс-тестирование, сервер выдержал 150 подключений, но не выдержала моя рабочая машинка :))  Я тогда считал, мы экономили для конторы примерно $20К :) (сейчас вероятно цена уже не актуальна). Сервер вел подробнейшие логи работы пользователей, все запросы падали в лог, поэтому мы всегда могли отыскать любые концы :) (и это было важно ввиду некоей борьбы между двумя отделами). Т.к. система работала на BSS (Borland Socket Server) (знаю, что плохо, но это был единственный приемлемый вариант) у нас были частые проблемы с обрывами связи (т.к. сам BSS кривой, да и инфраструктура нашей сети была далека от идеала), поэтому в серверную и клиентскую части был добавлен функционал обеспечивающий механизм сессий и решавший таким образом проблемы с обрывами.

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

p.s. Еще и армейскую работу вспомнить, чтоль...

четверг, января 11, 2007

Еще один Free

Обнаружил, что HTML Display Components стали бесплатными! Идеальное решение для HTML-интерфейса или отчетов в приложениях. К плюсам можно отнести независимость от сторонних движков и их версий, вследстие чего, однозначное отображение на любой системе. К минусам - не самое быстрое форматирование контента и скромные возможности управления внутренними объектами вследствие отсутствия поддержки DOM. Но мне, все равно, очень нравится ;)

понедельник, января 01, 2007

пятница, декабря 29, 2006

Инструменты, которые Free

Скорее речь даже не об инструментальных средствах разработчика, а о free-софте вообще. После выхода Turbo Delphi Explorer (которая free) у меня появилось желание если не отказаться от проприетарного софта совсем, то хотя бы свести его использование к минимуму. Как раз к этому моменту, вдоволь наэкспериментировавшись с Вистой (коею пользоваться не собираюсь, но в курсе быть нужно), решил начать с чистого листа, т.е. винта :) Вставил рекавери в свою Тошу и согласился на все, что мне предложили ;).

Итак:

  • ОС - лицензионная XP Pro SP2.
  • Браузер - Опера 9
  • Почта - Опера 9
  • Качалка - WinWGet (оболочка над консольной wget)
  • Аська - QIP
  • Блог-клиент - Windows Live Writer
  • Музычка - foobar 2000
  • Видео - Media Player Classic
  • Офис - OpenOffice (мне очень понравился)
  • CD писалка - с Тошей в комплекте идет Drag'n Drop CD+DVD (рядом поставил CDBurnerXP 3 Pro)
  • CD-виртуализатор - Алкоголь 120% (вечный триал ;) ибо мне хватает 3 дисков из 6 доступных)
  • Графика - GIMP, PhotoFiltre, XnView
  • 3D - Blender
  • Веб-дизайн - Nvu (мне показался удобнее дрима :)
  • Виртуалка - Microsoft Virtual PC 2004 (она же free!!!)
  • Архиватор - 7zip
  • Файл-менеджер - Far
  • Файрвол - Jetico Personal Firewall
  • Антивирус - Dr.Web CureIT!
  • Секурность - TrueCrypt
  • Программирование - Turbo Delphi Explorer, Ada GNAT
  • СУБД - FireBird (у него же есть embedded версия!!! ;) средство администрирования - IBExpert (для русских free!!!) (смотрел еще на Interbase Development Studio, но что-то она глючновата...)
  • Инсталь-мейкер - InnoSetup
  • Компоненты - множество бесплатных и разных ;) Условие только одно - наличие исходников. Очень нравятся: Synapse, UIB, ToolBar2000

Чему не нашел замены (может посоветует кто...):

  • Macromedia Fireworks (правда я его использовал не по назначению, а именно, как обычную рисовалку (т.е. его веб-ориентация меня мало интересовала). Может глянуть на Inscape или, как его там...)
  • AWIcons Pro - отличный редактор иконок
  • ReGet WebSynchronizer - отличный синхронизатор (я им бэкапы исходников делаю :)

вторник, декабря 19, 2006

И снова пакеты в Turbo Delphi Explorer

Ранее я уже писал о процессе подключения пакетов в Turbo Delphi Explorer, а теперь выкладываю модуль делающий это без необходимости саморегистрации подключаемых пакетов.

понедельник, ноября 13, 2006

Ловкость рук, и ни какого мошенства

Задача: дан класс имеющий приватный TThreadList (список с thread-safe доступом) и содержащий некие объекты. Нужно написать метод предоставляющий безопасный доступ к содержимому списка, без доступа пользователя к объекту-списку.

На первый взгляд задача совсем не простая т.к. для того чтоб обеспечить безопасный доступ необходимо вызывать методы блокировки/разблокировки объекта-списка, а условия нам этого не позволяют. На помощь приходят... интерфейсы (ну если быть точным, то лишь механизм подсчета их ссылок).

Решение: Определяем интерфейс IObjectProvider, который будет возвращать наш метод.

Type

IObjectProvider = Interface

Function GetObject : TObject;

Property Object : TObject Read GetObject;

End;

Затем описываем класс TObjectProvider, который реализует описанный ранее интефейс.

Type

//
TObjectProvider = Class(TInterfacedObject, IObjectProvider)

Private

FList : TThreadList;
FObject : TObject;

Public

Constructor Create(Const AList : TThreadList; AIndex : Integer);
Destructor Destroy; Override;

Function GetObject : TObject;

End;
//

// Реализация конструктора
Begin

FList := AList;
FObject := TObject(FList.LockList.Items[AIndex]);

End;
//

// Реализация деструктора
Begin

FList.UnlockList;
Inherited;

End;
//

// Реализация метода GetObject
Begin

Result := FObject;

End;
//


Теперь можно реализовать и наш метод:

Function SafeGetObject(AIndex : Integer) : IObjectProvider;
Begin

Result := TObjectProvider.Create(ThreadSafeList, AIndex);

End;

Как видно из кода, метод возвращает не сам объект, а интерфейс объекта-провайдера, для обеспечения безопасности. Пользователь вызвав метод и раскрыв его оператором with, получает в эксклюзивное пользование затребованный объект, а после завершения работы с объектом сработает механизм подсчета ссылок и будет вызван деструктор объекта-провайдера, который в свою очередь разблокирует список, после чего объект-провайдер будет разрушен.


Пример:

With SafeGetObject(5) Do
Begin

Object.Method;
...
Object.Method;

End;

воскресенье, ноября 12, 2006

Выравнивание вариантной части

Сегодня столкнулся с интересной штукой: вариантные поля (описанные с использованием case) записи могут быть выровнены по разному (ну компилятору ес-но виднее). В смысле не гарантируется что начало каждого вариантного поля будет сразу после последнего описанного не вариантного (или начала записи). Об этом, по большому счету, можно и не беспокоится до тех пор пока не придется обращаться к полям по смещению ;). Но об этом нужно помнить и быть аккуратным.

p.s. На packed записях не проверял.

понедельник, октября 30, 2006

Заменитель Indy

Не так давно открыл для себя сетевую библиотеку Synapse. Ощущения самые положительные. В отличии от монстра по имени Indy, Synapse являет собой легкую и элегантную оболочку над сетевой инфраструктурой сокетов. В настоящий момент, на ее основе, мною создаются транспортные уровни клиента и сервера XML-RPC (правда реализация на Indy, тоже предусматривается ;))

Глюкобага. Очередная...

Заколебало :( Сегодня снова столкнулся с очень неприятной багой компилятора (бага старая и ранее я ее описывал на iXBT).

Объявляем вложенный тип в записи. Пытаемся объявить поле данного типа и получаем от компилятора пламенный привет. А вот свойства объявленного вложенного типа определяются на ура. Есть workaround: объявить поле с типом допускающим приведение к объявленному, объявить свойство проблемного типа и в методах доступа (read/write) производить приведение типов (поле к свойству/свойство к полю). Дабы устранить оверхэд методов, объявить их, как  inline.

среда, октября 18, 2006

Маленькая радость

Америки я не отрою, если скажу, что с появлением динамических массивов и динамических строк жить стало легче, жить стало веселей :) Распределение памяти и управление временем жизни берет на себя компилятор, а мы можем избавится от выделения буферов средствами GetMem и ей подобным, т.к. такие массивы и строки являются по сути указателями на те самые буферы. И самое приятное, что такой буфер можно передать любой части программы без (даже временного) дублирования, т.к. компилятор использует механизм подсчета ссылок. Правда использовать такой буфер придется с приведением типа, но оно того стоит ;)

Пример:

s := 'http://www.borland.com/';


Stream.Write(Pointer(s)^, Length(s));

четверг, октября 12, 2006

Борис, ты не прав!

FAQ Apache, в части о сжатии запроса/ответа XML-RPC, говорит о том, что спецификация XML-RPC запрещает использование сжатия (и где они это нашли??). Считаю необходимым прояснить ситуацию. Спецификация XML-RPC требует: чтоб тип контента (Content-Type) запроса/ответа соответствовал text/xml, имелись некоторые обязательные заголовки (User-Agent, Content-Length) и не более того. Спецификация не запрещает применения сжатия к контенту (Content-Encoding), поэтому - Apache, ты не прав!

понедельник, октября 02, 2006

Enumerators (for-in-do)

Одним из самых заметных нововведений BDS 2006 является внесение в язык конструкции расширяющей оператор цикла For. For <container_item> In <container> Do; Переписывать сюда кусок документации не считаю нужным, и поэтому буду краток :) Лучше реализовывать перечислители в виде advanced-records т.к. при работе с ними не требуется динамического распределения памяти, а значит, код будет работать быстрее. Плюс удобнее работать с перечислителем вручную (не нужно создавать, не нужно финалить и разрушать), в случае необходимости. Правда сделать это (реализовать записью) не всегда удается, т.к. компилятор начинает ругаться на возвращаемый тип от GetEnumerator (видимо очередная глюкобага). Удачный пример перечислителя - перебор элементов XML документа, учитывая его структуру (каждый элемент может являться и родителем и ребенком) можно создать эффективный инструмент для перебора дочерних элементов любого родителя (хоть корня, хоть любого ребенка) с возможностью полного/близкого перебора. Сам перечислитель может обладать при этом указателем текущей глубины и номером элемента относительно начала перебора.

суббота, сентября 23, 2006

Счастливы вместе

Речь снова о TurboDelphi. Описаный ранее трюк с подключением пакетов перестает работать после установки вышедшего не так давно патча. Установка в среду пакета dclusr становится невозможной, а если он был ранее установлен то последующая его пересборка приведет к тому, что пакет из среды будет удален. Но есть решение: установить данный пакет до установки патча, код загрузки с прямым указанием загружаемых пакетов заменить на чтение списка пакетов из файла. После чего установить патч и не изменять dclusr.

четверг, сентября 21, 2006

Кодировки в XML-RPC

Неоднократно встречал в сети недовольные высказывания относительно того, что спецификация XML-RPC никак не регламентирует использование различных кодировок, в частности Unicode (и это, якобы, является минусом протокола). Но я считаю, что авторы этих высказываний (как и авторы библиотек включивших поддержку Unicode) не до конца понимают сути XML-RPC. Дело в том, что пакеты XML-RPC это лишь транспорт для данных приложения/сервиса и в каком виде данные должны предоставляться дело именно взаимодействующих сущностей, но ни как не протокола. На самом деле проблемы нет, как таковой. Ни что не мешает сервису предъявлять требования к передаче строк в кодировке, скажем UTF-8, если в том есть необходимость, а клиенту останется только "соответствовать". Такое требование затрагивает лишь данные, но не формат самого пакета. Таким образом и цель достигается, и происходит все в рамках спецификации. Выходит, что эта проблема "не в клозетах, а в головах" (c) Почти Булгаков :)

 

P.S.

Ну, а если вспомнить, что спецификация XML говорит об использовании UTF-8 во всяком случае, когда кодировка не может быть определена (не указаны Encoding и ByteOrder), то все становится просто и понятно, ведь пакеты XML-RPC не содержат ни того ни другого ;)

100 лет вместе с Turbo!

Позавчера получил CD c TurboDelphi 2006 Explorer! Спасибо Borland'у за бесплатную лицензию на 100 лет :) Правда в версии Explorer есть ограничение, а именно невозможность установки в среду сторонних компонентов. Но "ничего нет невозможного, для врача, для неотложного" (c) Розенбаум :), поэтому рецепт в студию: открываем пакет dclusr.dpk (это стандартный пакет пользовательских компонент и его установка допустима) и добавляем в него новый модуль инициализационная часть которого содержит код для загрузки необходимых пакетов:

Initialization

  LoadPackage('package_1.bpl');

  LoadPackage('package_1.bpl');

  LoadPackage('package_1.bpl');

Но это еще не все! Для успешности данной операции необходимо, чтоб загружаемые пакеты могли саморегистрироваться (в отличие от обычного способа, когда регистрацией занимается среда) т.е. в инициализационной части модуля/модулей необходимо вызвать процедуру Register. Теперь все :) При запуске среды будет загружен dclusr.bpl, который, в свою очередь, загрузит нужные нам пакеты.

пятница, сентября 15, 2006

Багафича, даже две...

На оператор класса Implicit (другие не пробовал) не действует директива Inline. Все условия для Inline соблюдены, но тело оператора не разворачивается в код :( И еще об Implicit: не удается добиться работоспособности данного оператора при декларировании с типами Double и TDateTime. Типы по описанию не идентичные, но компилятор, так, видимо, не считает... Поэтому, если описать неявное преобразование в Double, будет допустимо присваивание значения типа TDateTime, но при этом, разумеется, будет вызван метод Implicit для типа Double. Если же описать неявное преобразование для них обоих, будет потеряна всякая возможность присваивания значений данных типов. Такое вот, хреновое лето...