суббота, 29 июня 2013 г.

Почему в Delphi так и не появилось нормального аналога STL

Не понимаю....
Я свой "микро-STL" - конечно написал уже давно.

Но ПОЧЕМУ реальные производители этого не сделали?


Не понимаю....

А ведь отсюда - КУЛЬТУРА программирования проистекает...

P.S. и это при том, что у Borland в Turbo C++ УЖЕ была вполне себе ВМЕНЯЕМАЯ библиотека контейнеров.. Не помню уж как называлась.... Но пару курсовых работ я на ней написал...

(коллеги подсказывают - не Borland Data Structures?)

P.P.S. Тем более, что вот - http://18delphi.blogspot.com/2013/03/generic-generic.html

P.P.P.S. Если кому интересен "микро-STL" для Delphi - пишите. Постараюсь рассказать. Containers от Embarcadero - по оценкам других людей - проигрывают.

О "тормозах" в FireMonkey

Зачем создавать TMatrix (тем более, что она обычно - Identity) или TPosition в КАЖДОМ объекте? Или я отстал от жизни?

Я вот с VGScene провёл "тьюнинг" по этим вопросам. И стало - сильно легче.

Ну и закешировал "мелкие" часто используемые объекты.

P.S. Я всё хочу "провести тьюнинг" для текущего FM, как я сделал это для VGScene. Но - "руки не доходят"....

Я примерно понял - почему МНОГИМ программистам на Delphi не нужен UML

Доводя до "абсурда" - примерно так. Давайте всё запихнём в BD. Бизнес-логику впихнём в хранимые процедуры. Максимум что нужно - это Er-Win или его аналоги. И то - ДАЛЕКО не всегда...

А Delphi и код на нём - "ну что Delphi"... Там же "формочки".  Ну зачем там UML?

А там где SQL - "не ложится" - всё равно - ВПИХНЁМ SQL... ClientDataSet или MemTable.

"Выливаем воду из чайника"... А дальше - по накатанной...

Или я чего-то не понимаю?

Меня лично только удивляет ОДНО - как гиганты типа Apple, MS или IBM без UML и КОДОГЕНЕРАЦИИ - живут? Я вот лично - НЕ МОГУ.. А у них проекты - ПОБОЛЬШЕ моих будут наверное... Или они это ВСЁ ТЩАТЕЛЬНО скрывают?! Или БЕРУТ ЧИСЛОМ?

А как же тогда "мифический человеко-месяц"?

Или всё таки 9 женщин (или 99) могут родить ребёнка за месяц?

Почему у МНОГИХ программистов на Delphi РЕАЛЬНО случается ПАНИКА

Когда SomeClass превращается в SomeSuperClass.

Или "пропадает" стандартный метод (исходники которого есть).

Ах мы не будем переходить на новую версию! Ах там отрезали "чудные фичи".

А в код заглянуть?

Наболело....

Не понимаю.

О динамических массивах.. Уж очень они резво в Delphi 7 память "шинкуют"...

Упало тут:
    l_LeftLine.AddBounds(l_UpLine, l_DownLine, rColor, rDrawType);
Смотрим внутрь:
procedure Tl3FrameLine.AddBounds(aMinBound: Tl3FrameLine;
  aMaxBound: Tl3FrameLine;
  aColor: Integer;
  aLinePartType: Tl3LinePartDrawType);
//#UC START# *48CA578300F4_48CA54A000F7_var*
var                                 
 i          : Integer;
 l_Start    : Integer;
 l_Finish   : Integer;
 l_Start1   : Integer;
 l_Finish1  : Integer;
 l_FndIndex : Integer; 
 l_LinePart : Tl3LinePart;
//#UC END# *48CA578300F4_48CA54A000F7_var*
begin
//#UC START# *48CA578300F4_48CA54A000F7_impl*
 Assert((aMinBound <> nil) and (aMaxBound <> nil), 'Одна из границ отрисовки линии не задана!');
 Inc(f_BndArrayLen);  
 SetLength(f_BoundsArray, f_BndArrayLen);
– я почти уверен, что это из-за динамическоих массивов.  Это для информации.

"Сокровенные" заповеди

НЕ ИСПОЛЬЗУЙТЕ.

Не используйте

  1. TInterfacedObject. Беда там со счётчиком ссылок. Есть Tl3ProtoObjectRe: Так писать нельзя - будут утечки ресурсов2Re: MTDOrb.
  2. Динамические массивы. Почему нельзя пользоватся встроенными динамическими массивами Delphi. Есть l3AtomicListl3PtrListl3RefList.
  3. WideString. Потому же почему и динамические массивы. Только с ними всё ещё запущенней. Ибо это на самом деле объект Windows.
  4. Метод TObject.Free. Потому что остаются невалидные ссылки на уничтоженные объекты. Есть - FreeAndNilПочему FreeAndNil, а не Free.
  5. При прочих равных, значения параметров по-умолчанию. Особенно в локальных процедурах.  Без крайней нужды . Они крайне усложняют процесс чтения и понимания кода.  Попилить TdeDocInfo.IsSame на три атомарных метода.
  6. TObjectList. НИКОГДА, кроме случаев совместимости со стандартными библиотеками. Есть Tl3ObjectRefListTl3CObjectRefListTl3CBaseRefInterfacedListTl3SimpleObjectRefListl3UncomparabeObjectRefList,l3ObjectRefList и т.п. Re: Утечки памяти при работе программ БЧ.
    Достаточно положить один объект в два таких списка (TObjectList) и всё. Костей не соберёшь.
  7. Встроенные строки Delphi. Есть Tl3_String, Tl3WString, Il3CStringTl3PrimStringTl3ConstString.
  8. TStringList. Есть Tl3StringList.
  9. Временные задержки и таймеры я вообще не очень люблю, т.к. они недетерменированно ведут себя при отладке, поэтому стараюсь использовать по минимуму.
  10. Поведенческие флаги типа f_WasSomething - я тоже не особенно люблю, как и таймеры.
  11. Не злоупотребляйте ProcesMessages и "отложенной обработкой" через PostMessage. Они вредят друг другу. Причём - неожиданным образом. Re: МГО. Искажение в сообщении с предложением открыть документ в интернет-версии. Или - Re: List index out of bounds при печати текущей страницы из превью после выделения нескольких элементов списка.
  12. Якоря (Anchors). Они всё равно толком не работают. Особенно с большими шрифтами и Constraints. Используйте дихотомию и TvtPanel.

Естественно надо понимать, что абсолютный запрет не возможен.

Старайтесь

  1. Старайтесь чтобы число параметров функций влезало в доступные регистры.
  2. Использовать общую библиотеку. И исповедуйте декларативный, а не императивный подход. Учимся пользоваться общей библиотекой.
  3.  Настройки среды - W:\common\env\CommandFiles\.
  4. Разделять if с условиями OR и AND. 
    Пример: 

    Было:
     if ((aParts = nev_ripChildrenCnahged) or (aParts = [nev_ripHeight])) and (Obj.OverlapType = otUpper) then
    
    Стало:
     if (Obj.OverlapType = otUpper) then
      if ((aParts = nev_ripChildrenCnahged) or (aParts = [nev_ripHeight])) then
    
  5. Если вы считаете, что какое-то условие в коде 100% не должно выполнятся - пишите Assert.

среда, 26 июня 2013 г.

Чужая статья. Не знаю, что такое ORM, но идея - красивая

http://habrahabr.ru/post/184732/

Сам бы прикрутил. Если было бы куда.

P.S. Для таких же чайников как и я - http://ru.wikipedia.org/wiki/ORM

P.P.S. Честно скажу - "читал по-диагонали". Но мне достаточно самой идеи. Можно кстати наверное RTTI вообще в Run-Time "сварить" и в VMT запихнуть. Или через "automation".

P.P.P.S. Я кстати понял. 17-ть лет назад я в Diasoft пытался ORM сделать. Но не сложилось. По моей вине. Друзья "обратно" позвали. Не смог им отказать. Да и написание Эвереста тогда показалось важнее.

P.P.P.P.S. Вот ещё чужая статья, ну совсем "в жилу" - http://roman.yankovsky.me/?p=740

понедельник, 24 июня 2013 г.

Агрегация vs. Наследование

Пример из жизни.

Пусть мы хотим сделать "компонент", который наследуется от TClientDataSet и добавляет ему некие "прелестные фичи".

Вариант "в лоб"

TmySmartDataSet = class(TClientDataSet)
 constructor Create(anOwner : TComponent; тут много разных дополнительных параметров); reintroduce;
 ...
 inherited Create(anOwner);
 тут эти параметры используются

Сделали? Отлично!

И тут мы задумались о том, "а как нам "подсказать" будущему пользователю нашего "компонента", что в Design-Time его создавать не надо, и НАДО звать НАШ "кошерный" конструктор".

И ТОЛЬКО его!!!

По-моему - решение на поверхности - отказаться от наследования и сделать агрегацию. (Есть ещё вариант - "фабричный метод", это если ПОВЕДЕНИЕ менять не нужно. Но об этом - ПОЗЖЕ)

TmySmartDataSet = class(TObject)
 constructor Create(anOwner : TComponent; тут много разных дополнительных параметров); reintroduce;
 private
  FInnerSmartDataSet : TClientDataSet;
 public
  InnerSmartDataSet : TClientDataSet
   read FInnerSmartDataSet;
implementation
 TmySmartDataSetImplementation = class(TClientDataSet)
  //тут переопределяем ПОВЕДЕНИЕ
 ...
 FInnerSmartDataSet := TmySmartDataSetImplementation.Create(anOwner);
 inherited Create;
 тут эти параметры используются, чтобы довесить "чудные штучки" и "поднастроить"  FInnerSmartDataSet

Создаём так:
 l_MySmartDataSet := TmySmartDataSet.Create(anOwner, тут остальные "чудные" параметры);
 SomeDataSource.DataSet := l_MySmartDataSet.InnerSmartDataSet;

Идея понятна?

пятница, 21 июня 2013 г.

XPath кстати "тоже я придумал" :-)

http://ru.wikipedia.org/wiki/XPath

"Не буду врать - джентльменов удачи - не я снимал".

Но!

    with ParaX.rAtomEx([k2_tiSubs,
                       k2_tiChildren, k2_tiHandle,  ev_sbtSub,
                       k2_tiChildren, k2_tiByIndex, 0,
                       k2_tiHandle]) do
     if IsValid then
      IevSub(Obj) := l_SubList.Sub[AsLong]
     else
      IevSub(Obj) := l_SubList.Sub[-1];


Ничего "вчерне" не напоминает?

P.S. я КОНЕЧНО "всё читаю по-диагонали" и переосмысливаю... Но по-моему - похоже...

SAX и DOM

SAX и DOM - я когда-то "давным давно" - САМ ПРИДУМАЛ. А потом - СИЛЬНО УДИВИЛСЯ, что "всё придумано за нас".

Ну и "аналог" XSLT в виде всяких "фильтров/терминаторов".

Правда придумал - году так в 1998-м. Когда (подозреваю) в "промышленных масштабах" это до России ещё не дошло.

Ну или я книжек "правильных" тогда не читал...

Вот тут - SAX "на коленке" - http://18delphi.blogspot.com/2013/04/blog-post_5722.html

Там много "мусора", но это "исторически сложилось". И это не важно для понимания сути.

Не про Delphi. Но - "наболело". Мифы об XML и его "гибкости" и "универсальности"

За мою ДОЛГУЮ практику обработки документов я видел МНОГО людей которые приходили примерно с одним и тем же вопросом - "а вы можете вылить нам документы без потери качества и информации в XML?"

И ответ был - "да конечно можем. Вам всё равно в какой именно XML? Конкретная схема и DTD вас не волнуют?".

Люди обычно УДИВЛЯЛИСЬ и говорили - "да конечно - НЕ ВОЛНУЕТ, ведь XML - МОЖЕТ ВСЁ". (Иногда - спрашивали - "а что такое DTD").

Людям выдавали комплект XML "на пробу".

Некоторые - просто уходили.

Некоторые приходили и говорили - "ну это не то, что мы имели в виду".

Дальше начинались расспросы. Оказывалось, что люди НА САМОМ деле имели в виду КОНКРЕТНУЮ "реализацию" XML - конкретную схему или DTD (ну я - по-дилетантски объясняюсь). То ли это XMLDoc, то ли DocXML, то ли OpenDoc, то ли DocOpen.

И тут - ВСЁ ВСТАВАЛО на свои места! XML - это конечно КРУТО и ГИБКО. И "очень на волне". Но! МНОГИЕ под термином XML ПОДРАЗУМЕВАЮТ - "конкретную схему".

И если кто-то и слышал про XSLT. То - НЕМНОГИЕ. И опять же - если кто и слышал, то "в рамках КОНКРЕТНОЙ схемы".

Это я опять же - "по-дилетантски".

Это я всё к чему? XML - это конечно "круто и гибко", ну примерно как CORBA с её "динамическим получением описания интерфейсов".

Только - "совсем гибко и совсем круто" - ДАЛЕКО не МНОГИЕ могут оценить.

Ну ПРАВДА! Что делать с ОБЪЕКТОМ, интерфейс которого "известен только динамически"? Ну КРУТО - ДА! Никто - не спорит. НО ЧТО ДЕЛАТЬ? Разве только - "скрипты писать". Это - ДА. Это - можно.

И к чему я это?

Просто "серебряной пули нет".

МНОГИЕ слышали про XML. МНОГИЕ его используют. В СВОИХ нуждах.

Это - ДА - "круто и гибко".

Но ДАЛЕКО НЕ ТАК "круто и гибко" - чтобы "придти к другу" и сказать ему - "Эй Buddy - а вылей ка мне из своего проприетарного формата в XML".

Buddy - он конечно - клёвый парень - он выльет! Не вопрос!

Но ДАЛЕКО НЕ ФАКТ, что он выльет РОВНО ТО, что вы хотели.

Нет "серебряной пули". XML - "на вершине айсберга" - это не более чем - "набор стандартизированных скобочек".

Надеюсь, что я не утомил вас своим занудством...

P.S. я - дилетант в XML, но я, к сожалению, ПРОФЕССИОНАЛОВ ВЫСОКОГО РАНГА - и не встречал. Наверное - не повезло...

P.P.S. просто ещё я встречал такие вопросы - "зачем хранить данные в проприетарном формате, когда можно хранить в XML". Так и хочется спросить в обратную сторону - "А ЗАЧЕМ?". Чтобы данные выросли в 1.5-2 или даже ТРИ раза? СТО Гигабайт давайте умножим на 1.5. Что получим? То же относится и к вопросу - "а почему бы ТОТАЛЬНО не перейти на UNICODE?" Тоже хочется спросить - "а ЗАЧЕМ?" Чтобы данные выросли в ДВА РАЗА? ПРОСТО так... Ну или в 1.5 в случае с UTF-8. ЗАЧЕМ? Ради мнимой "крутости и гибкости"? А почему не пойти другим путём? Не хранить UNICODE только там где он РЕАЛЬНО НУЖЕН? Ведь - ЭТО ПРОСТО.

Простите за моё занудство... Лет через 5 - оно реально только ЗАНУДСТВОМ и покажется. Ведь - мощности и хранилищ и интернета - только растут...

Offtopic. Как так случилось, что я за 25 лет программирования "выучил" только TP/Delphi?

По мотивам - http://18delphi.blogspot.com/2013/06/blog-post_17.html.

Я такой "закостеневший"? Или ленивый? Или негибкий?

Или чаще надо было менять работу? Так - ЖАЛКО!!! Своё - РОДНОЕ.

Как получается, что люди в 25 лет пишут в резюме "множество всяких акронимов"?

Это реально так бывает? Или люди всё-таки немножечко лукавят?

Я вот тоже теперь - "типа знаю Objective-C и C++". Ну на Objective-C - я "типа год попрограмировал". А C++ - знал ещё вроде бы с времён школы/института. И даже пару курсовых на нём написал.

Но! Я ЛИЧНО - ПОНИМАЮ, что тот же Objective-C + UIKit - я знаю СИЛЬНО ХУЖЕ, чем Delphi + VCL. А уж про C++ - и говорить не приходится.




Я тут написал прототип функции - std::set<std::string> Lemmatize (const std::string & aWord).

И БЫЛ БИТ НОГАМИ. И в общем-то - за дело. Типа - "лишнее копирование". (Про C++ 11 и спецификатор && - НЕ ГОВОРИМ. Это пока - "в новинку". Хардкорным C++-программерам - это - ЧУЖДО).

Ведь:
void Lemmatize (const std::string & aWord, std::set<std::string> & theLemmas) - СИЛЬНО ЛУЧШЕ.

И это - правда. (Зачем делать язык, который АПРИОРИ - позволяет неэффективные конструкции - ОТДЕЛЬНЫЙ ВОПРОС - и он из раздела HolyWar. А я в них - стараюсь не участвовать).

А вы говорите - "знание C++". НЕ ЗНАЮ я C++.

ЧЕСТНО - "сам себе" - могу сказать, что "НЕ ЗНАЮ C++". Хотя и мог бы "теоретически" написать в резюме. Только резюме я никогда не писал. Не зачем было. В основном - только читал.

"Специалист - он подобен флюсу". Это - про меня.

ЧИТАТЬ C++ или Objective-C, или скажем "классический" FORTH, ну или FORTRAN - МОГУ. Но - НЕ ЗНАЮ.

КАК люди в 25-30 лет ухитряются РЕАЛЬНО ЗНАТЬ столько "акронимов" - НЕ ПОНИМАЮ.

Не понимаю...

четверг, 20 июня 2013 г.

Портирование на Delphi XE4 идёт вполне успешно

Портирование на Delphi XE4 идёт вполне успешно.

Всё меньше и меньше тестов не проходят.

Скорость работы правда существенно снизилась, так как я занимаюсь СОВСЕМ другими рабочими вопросами. Посему - портирую "в свободное от работы время".

ПРИНЦИПИАЛЬНЫХ сложностей не возникло, за исключением уже описанных ДВУХ ошибок - с открытыми массивами (http://18delphi.blogspot.com/2013/05/xe4.html) и "пустыми интерфейсами" (http://18delphi.blogspot.com/2013/06/blog-post_13.html).

С открытыми массивами - придумал workaround и жду update от Embarcadero (http://18delphi.blogspot.com/2013/05/resolved.html).

С интерфейсами - сложнее. Ошибка - плавающая. Пока "за хвост" - не поймал. Ловлю.

Ещё как-то странно себя ведёт TCanvas по сравнению с Delphi 7. Отдаёт ДРУГИЕ (немножко, буквально на пиксель) метрики шрифтов. И то - не всегда. Разбираться - пока не стал. Сделал для таких тестов ДРУГИЕ эталоны под XE4. По крайней мере - всё СТАБИЛЬНО работает в РАМКАХ новых эталонов. То есть - разница - систематическая, а не плавающая. Что УЖЕ радует. Если "ВДРУГ" будет "свободное время" - я конечно с этой разницей тоже поразбираюсь. Чисто из того, чтобы удовлетворить СВОЙ собственный интерес.

Пришлось ещё пока поправить "стандартные" ошибки VCL с которыми наши проекты - не живут (http://18delphi.blogspot.com/2013/06/embarcadero.html). Червь сомненья меня гложет - хочется сделать как-то по-другому. Без правки стандартного кода библиотек. Но я пока - не придумал как. Есть конечно опыт SuperVision и статьи от Багеля, про внедрение в код. Ну и "внерение в код" от ElPack/RX. Но я пока в этом - не очень силён. Всё ещё надеюсь придумать что-то менее хардкорное. Хотя бы "аккуратный" Cut'n'Paste на худой конец.

Серия про "ошибки" в VCL была тут - http://18delphi.blogspot.com/2013/04/vcl.html. Ну и рядом там. "Правки в VCL (N)".

Далеко не со всеми ПРИВЕДЁННЫМИ там правками наши проекты не живут. Но я уж привёл - ВСЕ известные правки. Так сказать "для полноты картины". Жаль, что нету "обратной связи"... Я думал - люди откликнутся... Начнут "бить ногами". Рассказывать, что "у меня руки кривые". Тишина... Тишина - она подозрительнее всего.

В общем - процесс идёт. Он пока не на "промышленной основе". Но идёт. Надеюсь, что всё будет удачно. И что и до 64-х бит - я тоже доберусь. А вот там - есть ВОПРОСЫ - http://18delphi.blogspot.com/2013/06/xe-64_7.html. ВОПРОСЫ - такие - СЕРЬЁЗНЫЕ. Что с НИМИ делать - ПОКА ВООБЩЕ - не знаю.

С правками VCL придумать бы что умное.... Чтобы не трогать стандартного кода.

Особенно вот этого:
procedure RegisterClass(AClass: TPersistentClass);
begin
  RegGroups.Lock;
  try
    while not RegGroups.Registered(AClass) do
    begin
      try
       RegGroups.RegisterClass(AClass);
      except {V}
       on E : EFilerError do
        if (Format(SDuplicateClass, [AClass.ClassName]) = E.Message) then
         // do nothing
        else
         raise;
      end;//try..except {/V}
      if AClass = TPersistent then Break;
      AClass := TPersistentClass(AClass.ClassParent);
    end;
  finally
    RegGroups.Unlock;
  end;
end;

"Хозяин кода" ведь в дом вернулся...

Ибо приведённый код - это ну совсем не ошибка. Хотя мне и не очень понятно - ЗАЧЕМ все родительские классы регистрировать. Ибо и без этого - вполне себе работает. Но! Это - ЗАТОЧКА, под "мои конкретные нужды" с "хоккеем" с примесями в компонентах. Мы правда всё равно от dfm скоро откажемся. В их классическом виде. Есть МНОГО насущных потребностей. Например - инстанцирование контролов в формах с разными классами реализации в зависимости от внешних условий. dfm это всё равно не позволяет. Ну и IfDef в dfm не бывает. А "очень хочется". Ну и про FireMonkey - есть у меня пара "шальных мыслей" - как "разом" проект с VCL перевести на FireMonkey. Опять же - через условное инстанцирование. Взять и "ловко подменить" VCL-ные контролы на контролы FM. И получить - ДВЕ ВЕРСИИ приложения - на VCL и на FM. Там конечно есть сложности, но они - решаемы. Наверное - максиму, что придётся - "выделять фасады". Как мне пока кажется. Это пока только в теории правда. Но я кое что - уже обкатал на практических примерах. В основном на VGScene правда. Но "окна - они и в африке окна". Про мультиплатформенность - пока вообще - НЕ ГОВОРЮ и НЕ ДУМАЮ. Пусть Delphi XE5 или XE6 выпустят :-) С их то темпами. Тогда - и буду думать. Я боюсь, что раньше - я всё равно не успею. Разве что только FM ОТДЕЛЬНО от РЕАЛЬНЫХ проектов опробовать. И всё таки - тесты написать.

Offtopic. Смотрю по телевизору сериал "форс-мажоры"

Смотрю. И думаю... Хорошо, что в программировании такого нет...

Замыкание...

http://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BC%D1%8B%D0%BA%D0%B0%D0%BD%D0%B8%D0%B5_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) Замыкание- не перестаю удивляться выразительной силе данной конструкции.. Она позволяет "портянки кода" сворачивать во вполне логичные блоки.. Читабельные для людей..

Мы тут когда ехали с конференции в Казани - я "в лицах" и "на пальцах" сидя на вокзале - рассказал коллеге про замыкания. И он - по-моему - понял. Это - СИЛЬНАЯ вещь.

Портянки кода - РЕАЛЬНО СВОРАЧИВАЮТСЯ.

P.S. В "моём" DSL для тестов в замыкание может быть передана ЛЮБАЯ функция. Так язык устроен.

Опять займусь самоцитированием. Из прошлого...

Из совсем прошлого:

"ещё до "открытия" для себя IUnknown я придумал "фабрики интерфейсов (инструментов)".. на базовом объекте я ввёл метод QueryTool, который возвращал по идентификатору "инструмента" либо новый объект, если текущий не был совместим с указанной VMT, либо текущий, если он был совместим с указанной VMT.. Но тут понадобился подсчёт ссылок (http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B4%D1%81%D1%87%D1%91%D1%82_%D1%81%D1%81%D1%8B%D0%BB%D0%BE%D0%BA)... и он - БЫЛ РЕАЛИЗОВАН... так вот.. а потом - я "открыл" для себя IUnknown, когда Delphi 3 вышли..."

Но в Delphi 3 - Не было TInterfacedObject (или я не знал про него). Посему - "мой подсчёт ссылок" - остался в неизменном виде. Он - СИЛЬНО отличается от TInterfacedObject. Хотя бы на +1 в конструкторе. И он дожил ДО СИХ ПОР. А ТЕПЕРЬ - он мне сильно нравится. ГОРАЗДО больше, чем TInterfacedObject. Он - СИММЕТРИЧНЕЕ. И позволяет "смешивать объекты с интерфейсами". Безболезненно. И не задумываться о const или не const.

+1 в конструкторе и "фабричные методы". Одна из разниц. Но какая!

Вот ссылка кстати - http://18delphi.blogspot.com/2013/04/iunknown.html

Ну и "ДО" IUnknown я сильно "баловался" процедурами с директивой message... Работало - как надо... Только - медленно.

От message я не так давно избавился... Лет пять назад...

А от QueryTool - так и не избавился. Они мне нравятся. Но только перевёл их на IUnknown.

Ещё буквально два слова про тесты

Просто сегодня услышал примерно то же самое от коллег.... Посему - повторюсь.

Пишите тесты на ВСЕ возможные "технические" предложения (в смысле sentence, а не proposal) из ТЗ. На ВСЕ которые ведут к той или иной логике кода. Насколько это ВОЗМОЖНО в вашем фреймворке и с вашим "порогом знаний" о тестах. Насколько возможно это сделать БЫСТРО. Если что-то не получается БЫСТРО - не стоит мучатся. Иначе вы будете говорить - "тесты замедляют мою работу". А я хочу добиться - РОВНО ОБРАТНОГО. (напишите один тест, два, пять, десять.. потом - горизонты - расширятся. Но это - вопрос времени)

Написано - "такие входные данные должны давать такие выходные" - пишем тест. Написано - "таких данных не бывает" - пишем тест (с assert). Написано "должна быть кнопка" - пишем тест. Написано - "из этого следует это" - пишем тест.

Вы удивитесь - насколько легко и быстро вы научитесь находить неточности и несогласованности в различных ТЗ.

Я ЛИЧНО - ещё ни разу не видел "идеальных" ТЗ. Особенно "в исторической перспективе". Когда одно ТЗ - влияет на другое. Написанное "скажем лет пять назад". И видимо это - "объективная реальность данная нам в ощущениях".

Мы не можем "сделать" или "добиться "идеального" ТЗ. Особенно "в исторической перспективе". Но мы можем ВАЛИДИРОВАТЬ эту "перспективу". И ВАЛИДИРОВАТЬ непротиворичивость РАЗНЫХ ТЗ.

Попробуйте. Я практически уверен, что вам понравится. Если вы конечно попробуете.

P.S. Ещё про тесты вот тут - http://18delphi.blogspot.ru/2013/05/blog-post_3529.html и вот тут - http://18delphi.blogspot.com/2013/05/blog-post_7.html.

понедельник, 17 июня 2013 г.

"Королевство в осаде" или "всё равно на чём писать"

Займусь самоцитированием. Раз уж ничего умного пока не получается:

http://www.delphikingdom.ru/asp/talktopic.asp?ID=250

"Жесть какое обсуждение я пропустил...
Не знал что такие страсти оказывается кипели.

В общем оно конечно - "всё равно на чём писать". Только куда девать многолетние наработки? Миллионы строк кода? Опыт опять же. Tips'n'tricks.

Проходить путь заново?

Я конечно тут попрограммировал например на xCode. Отчасти даже понравилось. Отчасти даже нашёл похожести с delphi - http://18delphi.blogspot.com/2013/03/objective-c-delphi.html

Но чтобы стать настоящим ПРОФЕССИОНАЛОМ - нужно время. Большое время. Мне так кажется.

Радует тот факт, что Delphi всё же вроде бы возрождается усилиями Embarcadero.

Только им надо ПЛОТНО с сообществом работать. Организовывать ЗАНОВО. Вдохновлять. Привлекать.

Сделать "центр компонент" например.

Тем кто "боится новых версий" и говорит, что Delphi 7 - самая лучшая - скажу - я вполне успешно мигрировал с Delphi 7 на Delphi XE3. Где-то за месяц-полтора. Один из проектов между прочим ~ 15 млн строк кода.

Так что - "не бойтесь".

С XE4 у меня правда возникли проблемы. Я написал баг-репорт (http://qc.embarcadero.com/wc/qcmain.aspx?d=116040). Надеюсь, что это поправят. Пока не поправили буду работать с Delphi XE3.

Тем более, что по лицензионной политике Embarcadero всем официальным пользователям доступны ВСЕ младшие версии."

Не знаю. Мне - "ВСЁ РАВНО" на чём программировать. Главное - ПРОГРАММИРОВАТЬ. Я нахожу в этом ИНТЕРЕС и ПОЛУЧАЮ УДОВОЛЬСТВИЕ. И попрограммировал я за эти годы на "таких" языках, которые МНОГИМ и не снились (и "однобуквенных" и "двухбуквенных"). Всякие DSL - чего только стоят. (сам ещё зачем-то "парочку" написал)

Но! Больше всего я всё же программировал на Delphi. И ТОНКОСТИ и ПРИЁМЫ программирования, и API, и то как "это компилируется в ассемблер" - я ЗНАЮ ТОЛЬКО для Delphi.

И его жалко БРОСИТЬ. (Пусть даже как тот "чемодан без ручки", хотя это и зло звучит наверное).

И поэтому - я ОЧЕНЬ РАД, что Delphi вроде как - ВОЗРОЖДАЕТСЯ, Со скрипом.. Но всё же... Если я конечно не ошибаюсь.

Как я говорил тут одному коллеге - "завидую я людям, иногда, которые меняют работу и проекты раз в два-три года - сделал и "забыл". Пусть дальше другие "отдуваются"...

У меня же - ДРУГОЙ случай. 

У "меня" иной код тянется с DOS (да да.. не смейтесь..), а иной - с Win16.

Я иногда смотрю - "МАКАРОНЫ КОДА!!! Кто??!! к ОТВЕТУ!!!"" Кто "Это" всё написал!!"

"Ах я.... Ах... Коллега с моей подачи... И Я его УБЕЖДАЛ в этом..." И уже как-то не так резко реагируешь... Иногда думаешь - "ПЕРЕПИСАТЬ ЭТИ МАКАРОНЫ ВСЕ с НУЛЯ!" И даже переписываешь. Особенно "ЧУЖИЕ" - и радуешься - "КАК ЛОВКО Я ВСЁ ПРИДУМАЛ, КАКОЙ ПРОСТОЙ КОД!"

Ан нет.. "дьявол - он в деталях"... Начинаешь разбираться - "и совсем не МАКАРОНЫ и совсем не ЗАПУТАННО"... Просто - бизнес-логика - ТАКАЯ СЛОЖНАЯ.. Да и объектов в системе - СЛИШКОМ МНОГО. РАЗНОРОДНЫХ. И уже как-то не так резко реагируешь...

"ну.. СЛОЖНАЯ СИСТЕМА"...

Не говоря уж о "смежниках"... Которых было ОЙ как немало...

UML-Диаграмма "всего что я попрограммировал" занимает наверное лист A0... На верхнем уровне... На уровне "проектных пакетов"...

И становится - отчасти - грустно... "Как же я тут глубоко и надолго залез..." А с другой стороны - РАДОСТНО... "ЗАТО КАК ДЕТАЛЬНО!!!..."

Я ЧИТАЛ - МНОГО разных резюме ДРУГИХ людей. ХОРОШИЕ РЕЗЮМЕ. Много разных "букв и акронимов". Delphi, C++ (strong! ОБЯЗАТЕЛЬНО), STL, Boost,C#, Objective-C, Multithreading, InfoCube, SAX. DOM, COM, DCOM, CORBA, FORTH, LISP, Ajax, SOAP, PL/SQL, ORACLE, DB2, MSSQL, SQLLite.

Иногда ДАЖЕ - ЭТО ВСЁ в ОДНОМ резюме. Плюс "немножко администрирования", плюс LINUX, плюс TP/IP, плюс iOS.

Да. Я тоже "немножко программировал на xCode" и даже кое-что - написал. Но это не сравнится с опытом приобретённым в TP/Delphi.

Я тоже - "где-то слышал" все эти "слова и акронимы". Но! В СВОЁМ СОБСТВЕННОМ резюме я ПО-ЧЕСТНОМУ - могу написать лишь одно слово - "DELPHI". Всё остальное - будет неправдой - с той или иной точки зрения. (Там есть несколько ещё "акронимов", которые я знаю "детально", но боюсь, что "широкая публика" их не поймёт :-( )

ПОЭТОМУ - мне бы ОЧЕНЬ ХОТЕЛОСЬ БЫ, чтобы Delphi - ВОЗРОДИЛСЯ. Ну пусть и в несколько ином качестве.

Пожелаю  команде Embarcadero - "ЛАЖАТЬ ПОМЕНЬШЕ!!!". Искренне!

ГЛАВНОЕ - ВЫДЕРЖИВАТЬ ЛИНИЮ. Не заниматься "разбродом и шатанием", а ИМЕННО - ВЫДЕРЖИВАТЬ ЛИНИЮ. Чёткую.

Я на них - СМОТРЮ с НАДЕЖДОЙ. И продолжаю портирование УЖЕ под XE4 (и 64 бита - НАДЕЮСЬ).

P.S. Что до "акронимов" - я даже когда-то на FORTRAN и asm PDP-11 программировал.... Но КОМУ ЭТО нужно теперь?

P.P.S. Как я уже сказал - "МНЕ ТОЖЕ ВСЁ РАВНО на чём писать". Но ГАРАНТИРОВАТЬ КАЧЕСТВО я ЛИЧНО могу на очень узком спектре инструментария. Может быть - опять же - я ОДИН такой "неудачник"... Ну или перфекционист?

P.P.P.S. А уж сколько "ЧУДНЫХ КУНШТЮКОВ" у нас в организации сделано вокруг Delphi, DUnit, DSL и UML... О! Пальцев не хватит - перечесть... Я лично - "заложник" ХОРОШИХ ТЕХНОЛОГИЧЕСКИХ РЕШЕНИЙ... "Проект на два-три года" - явно не про меня....

четверг, 13 июня 2013 г.

Offtopic. Слов нет.. "Высокие" и "низкие" программисты...

Это что-то. ДАВНО я подобного не видел:

https://www.youtube.com/watch?feature=player_embedded&v=fhWhb88GsL4

Слава БОГУ - я этого не КАСАЛСЯ... Наверное "там где-то пилятся деньги"...

ХОТЕЛ бы ошибаться, что ЭТО не ТАК.

Что касается ИМЕННО "зерна" ЭЛЕВАТОРОВ и зернохранилищ.

Я считал ОДИН ДИПЛОМНЫЙ проект. В ПИЩЕВОМ ИНСТИТУТЕ. И этот ДИПЛОМ - был ЗАЩИЩЁН. Так что - "наверное" - я имею представление о чём речь.

Так что - НАВЕРНОЕ - я не на пустом месте рассуждаю.

Все эти ЭЛЕВАТОРЫ, трубы, насосы, фильтры - это не более чем ЗАКОНЫ КИРХГОФА. С "местными" коэффициентами.

Труба == проводник.
Насос == ЭДС
Фильтр == сопротивление

Сумма входящих потоков - равна сумме исходящих. ИНАЧЕ - НИКАК - особенно с зерном.

Падение "мощности" (насосов) - равно падению напряжения.

Падение напряжения "по контуру" - равно сумме ЭДС (насосов в этом контуре).

Как-то так.

Люди, которые не "работали у станка" и не "копали землю"- рассуждают о "высоких" и "низких" программистах. Позвольте уж ХОТЯ БЫ - чтобы сами ПРОГРАММИСТЫ, судили о "себе подобных". А не какая-то "тётя из телевизора".

Простите уж за резкость.

Как говорит мой сын - "ну что ты мной всё "коммандируешь""... я боюсь ему рассказать, что у него два пути - либо в суворовское училище, либо в академию управления... с такими-то замашками...

P.S. Не говорю уж о том, что "инженеры" 1C - одни из САМЫХ высокооплачиваемых. На этом "так называемом рынке". Но это - ФАКТ. Так что - кто "низкие", а кто "высокие" - ещё - ВОПРОС.

Новый коллега тут долго и мучительно искал ошибку в МОЁМ коде

"Новый" коллега тут долго и мучительно искал ошибку в МОЁМ коде. И в итоге - НАШЁЛ. Меня к этому процессу особо не привлекали - ну такое по-моему бывает везде - "мол конечно ты за 5 мин найдёшь, но с одной стороны - у тебя своих задач хватает, а с другой стороны - "пусть парень поиузучает"". А если что мол - "проконсультируешь". Что ХАРАКТЕРНО - "парень" - долго ВДУМЧИВО "курил" исходники, а потом написал мне комментарий, что "мол так и так, проблема в этом". И (как я сейчас понимаю) - комментарий был КРАЙНЕ вдумчив и КОРРЕКТЕН, и при этом описывал проблему ПРАКТИЧЕСКИ ПОЛНОСТЬЮ. Но мне что называется "было недосуг" и я "находился в плену собственных стереотипов" - ГДЕ БЫ эта ошибка могла бы быть. И я направил коллегу по ЛОЖНОМУ следу. Я вывалил на него МАССУ "полезной", но в принципе - НЕ ОТНОСЯЩЕЙСЯ к делу информации. Что мол - "я бы копал бы там-то и там-то". Что характерно - никакой "стены отчуждения", или нежелания помочь - не было. Мы потом не раз эту проблему обсуждали устно в курилке. С интересом. И всё дальше и дальше я направлял коллегу по ЛОЖНОМУ ПУТИ.

Потом - "СЛУЧИЛОСЬ ЧУДО". Мы вернулись на новый виток. Коллега был вдумчив и упорен. И на НОВОМ ВИТКЕ он мне написал СВОЙ ПЕРВЫЙ КОММЕНТАРИЙ. Ну СЛОВО В СЛОВО. Я его прочитал ВНИМАТЕЛЬНО и сказал - "ну вот же в чём проблема"! "Чего ж" ты мол раньше молчал! Вот "в этом" и "этом". И проблема - решилась.

Я правда потом (случайно) - перечитал самый ПЕРВЫЙ комментарий. И осознал, что там написано - РОВНО ТО ЖЕ САМОЕ. Что и в том комментарии, который РЕШИЛ проблему.

Мне стало даже "стыдно". За то что, что попусту потратил чужое время.

Я даже сказал коллеге об этом. Правда услышал в ответ - "зато я столько интересного узнал". И это кстати - правда. Может быть это конечно и к лучшему. Но к ДАННОЙ КОНКРЕТНОЙ проблеме это НЕ ОТНОСИЛОСЬ.

И вопрос КОММУНИКАЦИЙ (свой "резкий" стиль я - опущу, я - работаю на этим) и ПЕРЕДАЧИ знаний - как мучала меня ещё лет 10-ть назад - так и мучает. Непонятно, что с этим делать. Другие коллеги говорят - "пиши документацию". Я правда спрашиваю - "какую именно" и на этом обычно разговор - заканчивается. Потому что ответ - обычно не находится. Документов то - МНОГО. Но на КОНКРЕТНЫЕ сиюминутные вопросы - НЕПОНЯТНО как там найти ответ.

Но! в Этом КОНКРЕТНОМ случае - мне коллега сказал - "я почитал документацию. Там "почти" всего хватает". "Хорошая документация" - сказал он. Ну как-то так. При том, что эту документацию как раз НЕ Я писал. Мне тут "гордится" нечем. Я как раз там просил других коллег написать - как ОНИ это понимают. Ну чтобы не было такого - "ну тут всё понятно..."

И ВСЁ РАВНО - я НЕ ПОНИМАЮ - как передавать знания и как правильно читать чужие комментарии, в которых УЖЕ СОДЕРЖИТСЯ ответ.

Если я ОДИН такой - это пол-беды. Но что-то мне подсказывает, что это проблема ОТРАСЛИ.

Извините, если отвлёк ваше внимание без дела.

P.S. Другой коллега. Правда уже бывший. Прочитав сей пост спросил - "ну и долго ты его по-ложному следу водил?" Это он тоже кстати "не со зла" :-) Просто - УДИВИЛСЯ.

Есть у меня ПОДОЗРЕНИЕ, пока только ПОДОЗРЕНИЕ

(Беспочвенные подозрения у меня кстати ОДИН раз были уже - http://18delphi.blogspot.com/2013/04/delphi-xe.html) (а проблемы на самом деле были вот в этом "хоккее" - http://18delphi.blogspot.com/2013/04/getmem.html)

Что в Delphi XE4 - "пустые интерфейсы" иногда - "глючат".

Типа

IA = interface
 SomeMethod
end;

IB = interface(IA)
end;

TA = class(TInterfacedObject, IA)
end;

TB = class(TA, IB)
end;

Так вот если получать TB - как IA - то ВСЁ хорошо. А если получать как IB. Который в общем "по сути" такой же как IA, то наблюдаем проблемы при присвоении интерфейсным переменным (которое генерирует компилятор). ПАДАЕТ на _IntfCopy. К сожалению - JEDI - стек НЕ ПОКАЗЫВАЕТ. (Кстати - а есть ли всё ТАКИ УЖЕ АВТОРСКИЙ JEDI под XE4? http://18delphi.blogspot.com/2013/05/jedi-xe4.html) Проблемы - РЕДКИЕ. Но что характерно под XE3 - НЕ ПРОЯВЛЯЮЩИЕСЯ. Может быть это - СУГУБО НАШИ проблемы. И если я их найду - я обязательно напишу про них.

Я к чему? Если - ВДРУГ у кого-то проявляются ПОДОБНЫЕ непонятные. И нестабильно повторяющиеся проблемы. С похожими симптомами - может быть вы будете так любезны, что напишете мне про них? Ну вдруг?

Ещё раз напомню - "в моём случае" - проблемы есть ТОЛЬКО под XE4. По XE3 - НИ ОДНОГО случая - ДОКУМЕНТАЛЬНО зафиксировано не было.

Ничего пока не УТВЕРЖДАЮ. Но "вдруг"...

P.S. Падения под XE4. На НАШЕМ КОДЕ (прямо скажем непростом) - зафиксированы ДОКУМЕНТАЛЬНО. В логах тестов. К сожалению - пока БЕЗ стека. Может быть - это и СУГУБО наши (тогда уж - МОИ) проблемы. Но странно мне как-то. Что под XE3 - не вылезло. Не найду "хвостов" - буду тщательнее под XE3 гонять. Может какие мысли появятся.

Коллега сегодня разбирался с нашими непроходящими тестами под XE4

Коллега сегодня разбирался с нашими непроходящими тестами под XE4. Которые ПРОХОДЯТ (стабильно !!! и "МНОГИЕ годы") под Delphi 7. И нашёл ОЧЕНЬ странный баг. Наш. Где мы "заложились" на стратегию работы менеджера памяти. На самом деле сами того не подозревая. Баг был поправлен. Тесты заработали.

Баг на самом деле - очень показательный. Правда - не знаю - с какого конца его бы начать описывать.

В двух словах. "Совсем на пальцах". Брался указатель на объект. И "зачем-то" он считался его уникальным идентификатором. И со сменой стратегии менеджера памяти - ЗНАЧЕНИЕ этого указателя - СТАЛО вести себя ПО-ДРУГОМУ.

Почему? История уходит в глубь времён. "Говнокод" - спросите вы? "Ну наверное" - скажу я. Если бы это был МОЙ код, то я бы так и сказал. Но поскольку код чужой - скажу осторожнее. "Наверное на то были веские причины".

Суть истории пока такова - смена стратегии распределения памяти - может принести "сюрпризы", о которых многие даже не задумываются.

ОЧЕНЬ хотелось бы описать - суть РЕАЛЬНОЙ проблемы, но я пока думаю - как это правильнее сделать.

P.S. Под XE3 такое кстати "меньше" проявляется. Но это правда пока ни о чём не говорит.

P.P.S. Я как собака - "понимать - понимаю, а сказать - не могу".

Совсем не Offtopic. Чужая ссылка. Мда...

"Чему я научился за 8 месяцев в Microsoft":

http://habrahabr.ru/post/183130/

P.S. постараюсь быть осторожным. Если и вправду в MS - ТАК, как ТАМ  написано, то МНОГИЕ компании (Российские), которые я видел (и в частности и та в которой я работаю) - для меня как для разработчика - СИЛЬНО ПРИВЛЕКАТЕЛЬНЕЕ. Ну или ДЕЙСТВИТЕЛЬНО у MS - проблема МАСШТАБА?

понедельник, 10 июня 2013 г.

Offtopic.Прочитал тут в одном ТЗ....

НЕ НАШЕМ...
"Это сделать - КРАЙНЕ важно".... За подписью "и выше и выше"...
Только один вопрос МЕНЯ волнует - а "что всё остальное ТАК не важно"?

ТО ЕСТЬ... Бывают ТЗ ВАЖНЫЕ.. А бывают "просто так"?

суббота, 8 июня 2013 г.

Мне вот интересно

"Как пасти котов"
"Фронтовые очерки"
"Джоэл о программировании"
"Мифический человеко-месяц"
"Роман об управлении проектами"
"Психбольница в руках пациентов"
"Джоэл снова о программировании"
"GoF"
"Применение абстракций и спецификаций в разработке ПО"
-- это вообще в России (!!!) кто-нибудь, кроме "кодеров" читал?

Цитата

"Вы слишком КВАЛИФИЦИРОВАННЫ (overqualified) для роли аналитика... над не надо ДЕТАЛЬНОГО погружения в код...".. Из РЕАЛЬНОЙ переписки... :-) Уже многолетней давности.

P.S. Я понимаю, что это "вежливый отказ". Но уж очень как-то не вяжется с моими представлениями...

пятница, 7 июня 2013 г.

Собрал один "микроскопический" проект под XE 64-бита

Собрал один "микроскопический" проект под XE 64-бита. Работает. Но появилось много вопросов - "что делать дальше".

Первый вопрос - что же делать со своими "лямбдами". Заменять на reference to function под IfDef? По всему коду?

Что делать с ассемблерными вставками? 64-битного ассемблера - я банально - НЕ ЗНАЮ. А уж особенностей компилятора и построения кода - так и подавно.

вторник, 4 июня 2013 г.

Насколько кстати Embarcadero "смотрит криво" на правку тех исходников, которые она поставляет?

Насколько кстати Embarcadero "смотрит криво" на правку тех исходников, которые она поставляет?

Надо сказать, что ДАЛЕКО НЕ ВСЕ собираются. И не только System.pas. Хотя и его мы когда-то умели собирать. С ключём -Y.

Но и без того - хватает.

Банальный пример - Variants, или ZLib.

И вот тоже пример - http://18delphi.blogspot.com/2013/06/hashlittle-overflowchecks-off.html

Или это "вообще запретная тема"?

И вообще - Embarcadero - восприимчива к дискуссиям - "как бы поправить исходники"? Например в Classes.pas, например для "примесей" в компонентах.

Например вот:
procedure RegisterClass(AClass: TPersistentClass);
begin
  RegGroups.Lock;
  try
    while not RegGroups.Registered(AClass) do
    begin
      try
       RegGroups.RegisterClass(AClass);
      except {V}
       on E : EFilerError do
        if (Format(SDuplicateClass, [AClass.ClassName]) = E.Message) then
         // do nothing
        else
         raise;
      end;//try..except {/V}
      if AClass = TPersistent then Break;
      AClass := TPersistentClass(AClass.ClassParent);
    end;
  finally
    RegGroups.Unlock;
  end;
end;

Или Embarcadero имеет свою политику и не хочет даже ввязываться в дискуссии?

Например они говорят - "все ваши правки - это ваша головная боль". Или нет?

Вот скажем "примеси через include" это вообще комильфо? Или стоит задумываться об из замене? Если о замене, то я честно говоря - пока не знаю как. Да и вообще не уверен - возможно ли это.

Просто если Embarcadero "смотрит на это косо", то нам что-то надо с этим делать. У нас написан не один десяток миллионов строк кода....

А если "не криво", то хотелось бы рассказать о "своих чаяньях". Их по-сути - не много... Приведённый ВЫШЕ код - САМЫЙ критичный. Если мы не сможем компилировать Classes.pas, с подобными правками - мы не сможем компилировать свой код вообще. А значит - мы останемся "в рамках Delphi 7". Когда "код был ничей".

P.S. Ну есть конечно "другой путь" (которым мы и так идём, потому что мы думали, что Delphi - умер) - отказ от dfm и RAD и замена их на UML. И "в пределе" мы рассматривали Free-Pascal. Хотя там тоже - ЕСТЬ ПРОБЛЕМЫ, но там как минимум есть исходники компилятора.

Хотя хотелось бы НАОБОРОТ - "вернуться в рамки RAD и dfm". Но хотелось бы конечно в новом качестве.

Если бы "меня спросили" что делать с dfm - я бы ответил бы - "уходить от абсолютных координат". Относительные Layout'ы. Не более того. С процентами или constraint'ами. Ну и КОНЕЧНО - я бы сделал бы возможность КОММЕНТАРИЕВ в dfm.

Это "и мне" с UML - "на руку". В комментариях же можно - "мета-информацию" зашивать.

P.P.S. И конечно хотелось бы возможности "зашития" в dfm НАСТОЯЩЕЙ мета-информации. Например тех же АТРИБУТОВ. Ну и конечно IfDef. Ну и комментариев конечно же. Повторяюсь..

P.P.P.S. А ещё бы я конечно "скрестил" бы dfm, Visual Live Binding и UML, и (возможно) ER. Тогда - будет РЕАЛЬНЫЙ RAD.

P.P.P.P.S. Под возможностью "скрестить dfm с RAD и UML" я подразумеваю следующее - "рисуем" на dfm "контролы" ввода/вывода и "мапируем" их на "бизнес логику". ПОХОЖЕ на VLB! И может быть - это оно "где-то и есть". Тут надо додумать. Просто в моём представлении - "бизнес-объекты" - не просто "Observer", а скорее - "микросхемы", со входами и выходами. Тут надо додумывать. У меня-то есть своя "разрисовка" всей этой концепции, но она во-первых - не факт, что правильная, а во-вторых - "ДСП"... О! Оно - "проприетарно"...

Но! "Мои" бизнес-объекты, формы и "сборки форм" - гораздо продвинутей VLB. Мы даже пытались делать свои "редакторы свойств", визарды, шаблоны приложений и форм. И даже пользовались этим лет 5. Но ушли на UML - ибо - "изобразительных средств не хватило".

А ведь сколько! Споров было "бизнес-объект" или УЖЕ не "бизнес-объект", а ПРЕДСТАВЛЕНИЕ. А ГДЕ реализация ПРЕЦЕДЕНТА? А где данные? А где ПРЕДСТАВЛЕНИЕ? А как на уровни делить?

Publisher/Subscriber? Или Operation?

Кстати - "GoF" - я бы как-нибудь "втиснул бы" в рамки RAD. RAD без GoF (или чего-то подобного) - это - "школота". Простите уж за резкость... :-(

"Кидать на формы компоненты и определять ОБРАБОТЧИКИ", это мне РАЗОНРАВИЛОСЬ через ГОД общения с Delphi. Хотя это и КРУТО!

У меня и VCM родилось с "противовес" киданию компонентов на формы - http://18delphi.blogspot.com/2013/03/vcm.html

Добрались мы до той ситуации, когда тесты не проходят на ВСЕХ машинах

Добрались мы до той ситуации, когда тесты не проходят на ВСЕХ машинах.

И при этом - КОД ведёт себя - ПРАВИЛЬНО. Ну насколько он может. Себя "правильно вести".

Пока додумались только до "квантификаторов" типа EtalonNeedsComputerName (самое волюнтаристское), EtalonDependsFromOS, EtalonDependsFrom64System.

P.S. И далеко не ВСЁ кстати зависит от нас. Мы например выяснили один простой факт, что в 32-битном приложении exception под OS 64 "тупо" не всплывает из Windows-процедуры. WinProc. В итоге - то, что является ошибкой под 32 бита - отнюдь не является таковой под 64 бита. Мы что-то не так делаем? Руки у нас кривые?

"Анти-тест" vs. "этот код должен падать (поднимать исключение) по ТЗ"

"Анти-тест" vs. "этот код должен падать (поднимать исключение) по ТЗ". Грань ясна? Проблема понятна? Тут хотелось бы подискутировать....

Понятно, что "анти-тест" - это ВРЕМЕННАЯ мера, до тех пор пока ошибка не будет исправлена. А второй вариант - "высечен в бронзе". Ну ДОЛЖЕН код "падать" по ТЗ. Ну граничные условия не те. Или пользовательский ввод не тот.

И хотя - поведение "системы тестирования" в ОБОИХ случаях - может быть ОЧЕНЬ ПОХОЖИМ - но на уровне разработчика тестов - эти два случая - КАРДИНАЛЬНО различаются. И разработчик тестов должен понимать это "внутренним чутьём".

По-моему - это - интересная проблема.

понедельник, 3 июня 2013 г.

Offtopic. Человек написал...

"Не могли бы Вы мне помочь с компонентами ExprDraw и ExprMake?"

Я ответил - "с удовольствием. Чем именно помочь?"

И тишина... Наверное - помог :-) Поддержал так сказать морально...

P.S. Тем кто спрашивает "как встроить формулу в MEMO-поле" - я бы посоветовал бы почитать GoF ("Банду четырёх"), хотя бы главу про "глифы". Формула (или картинка) и есть - "глиф". Подумайте об этом. На том месте, где можно вывести "символ" - можно вывести и "глиф". Достаточно ПЕРЕОПРЕДЕЛИТЬ высоту/ширину "глифа", а также функцию отрисовки. И - дело в шляпе. Ещё можно посмотреть на xCode и поискать в интернете - kCTRunDelegateAttributeName . Например - http://www.pvsm.ru/ios-development/29392.

P.P.S. http://ru.wikipedia.org/wiki/%D0%93%D0%BB%D0%B8%D1%84

P.P.P.S И ещё раз - http://18delphi.blogspot.com/2013/04/blog-post_10.html и http://18delphi.blogspot.com/2013/04/blog-post_8517.html

P.P.P.S. Т.е. если стоит задача "вывести формулу (или картинку) в MEMO или RichEdit", то вы просто вешаете "обработчик" на отрисовку (и измерение ширины/высоты) КАЖДОГО символа, и дальше в этом обработчике - делаете всё, что вам заблагорассудится. Как то так.. Дальше нужен пример?

P.P.P.P.S. Ещё раз - Картинка (или формула) и есть - "символ", т.е. - "глиф". КАЖДЫЙ "глиф" имеет свои метрики (ширину и высоту) и функцию отрисовки. Думайте так, как будто "кто-то" рисует за вас этот "глиф" (и измеряет его). А если хотите чего-то сложного типа формулы или картинки - поймите, что именно вам эти функции и надо обеспечить.

P.P.P.P.P.S. "Рецепта" на ВСЕ СЛУЧАИ жизни - я вам не дам. Разве, что только устно. Да и то - не факт. Можно выложить "супер-компонент", рисующий и текст и картинки и формулы, но там опять же - будут вопросы. Много вопросов. Проще "дать удочку", нежели "накормить рыбой".

Запустил сегодня проекты собранные под XE4

Придумал workaround бага компиляции. И запустил сегодня проекты собранные под XE4. Тесты показывают навскидку не худшие результаты, чем под XE3.

HashLittle не работает БЕЗ OverflowChecks Off

function HashLittle(const Data; Len, InitVal: Integer): Integer;
var
  pb: PByte;
  pd: PCardinal absolute pb;
  a, b, c: Cardinal;
label
  case_1, case_2, case_3, case_4, case_5, case_6,
  case_7, case_8, case_9, case_10, case_11, case_12;
begin
  a := Cardinal($DEADBEEF) + Cardinal(Len shl 2) + Cardinal(InitVal);
  b := a;
  c := a;

  pb := @Data;

  // 4-byte aligned data
  if (Cardinal(pb) and 3) = 0 then
  begin
    while Len > 12 do
    begin
      Inc(a, pd[0]);
      Inc(b, pd[1]);
      Inc(c, pd[2]);
      Mix(a, b, c);
      Dec(Len, 12);
      Inc(pd, 3);
    end;

    case Len of
      0: Exit(Integer(c));
      1: Inc(a, pd[0] and $FF);
      2: Inc(a, pd[0] and $FFFF);
      3: Inc(a, pd[0] and $FFFFFF);
      4: Inc(a, pd[0]);
      5:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FF);
      end;
      6:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FFFF);
      end;
      7:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1] and $FFFFFF);
      end;
      8:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
      end;
      9:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FF);
      end;
      10:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FFFF);
      end;
      11:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2] and $FFFFFF);
      end;
      12:
      begin
        Inc(a, pd[0]);
        Inc(b, pd[1]);
        Inc(c, pd[2]);
      end;
    end;
  end
  else
  begin
    // Ignoring rare case of 2-byte aligned data. This handles all other cases.
    while Len > 12 do
    begin
      Inc(a, pb[0] + pb[1] shl 8 + pb[2] shl 16 + pb[3] shl 24);
      Inc(b, pb[4] + pb[5] shl 8 + pb[6] shl 16 + pb[7] shl 24);
      Inc(c, pb[8] + pb[9] shl 8 + pb[10] shl 16 + pb[11] shl 24);
      Mix(a, b, c);
      Dec(Len, 12);
      Inc(pb, 12);
    end;

    case Len of
      0: Exit(c);
      1: goto case_1;
      2: goto case_2;
      3: goto case_3;
      4: goto case_4;
      5: goto case_5;
      6: goto case_6;
      7: goto case_7;
      8: goto case_8;
      9: goto case_9;
      10: goto case_10;
      11: goto case_11;
      12: goto case_12;
    end;

case_12:
    Inc(c, pb[11] shl 24);
case_11:
    Inc(c, pb[10] shl 16);
case_10:
    Inc(c, pb[9] shl 8);
case_9:
    Inc(c, pb[8]);
case_8:
    Inc(b, pb[7] shl 24);
case_7:
    Inc(b, pb[6] shl 16);
case_6:
    Inc(b, pb[5] shl 8);
case_5:
    Inc(b, pb[4]);
case_4:
    Inc(a, pb[3] shl 24);
case_3:
    Inc(a, pb[2] shl 16);
case_2:
    Inc(a, pb[1] shl 8);
case_1:
    Inc(a, pb[0]);
  end;

  Final(a, b, c); <<----- падает тут
  Result := Integer(c);
end;

Вообще конечно комильфо было бы, если бы авторы предварили функцию директивой OverflowChecks Off.

суббота, 1 июня 2013 г.

Жёсткая проектная организация на долговременной основе имеет ОДИН БОЛЬШОЙ МИНУС

Жёсткая проектная организация на долговременной основе имеет ОДИН БОЛЬШОЙ МИНУС - люди, да и сами проекты склонны "замыкаться в себе"... и всё что происходит ВОКРУГ они воспринимают как факторы раздражения или белый шум... 

если бы меня спросили что делать - я бы активно перемешивал бы людей между проектами.. 

гораздо проще "послать" некоего абстрактного человека "неизвестно откуда", нежели человека с которым вместе поработал.. и не просто поработал, а вместе решил какие-то конкретные задачи.. и ПУД СОЛИ вместе съел... 

да и флаги типа "вы со своим файл-серверным подходом.." в момент бы выкинулись.. потому, что каждый бы ощутил себя в шкуре другого... это касается и "представителей заказчика" (если это конечно не совсем РАЗОВЫЙ проект).. "представители заказчика не должны быть "сбоку" или "над".. они должны быть внутри..

Мне КАЖЕТСЯ - НАДО перемешивать людей между проектами. И между РОЛЯМИ. Чтобы людям было ТРУДНО говорить - "вот я бы на твоём месте.."

Чтобы люди ПОБЫЛИ на ЧУЖОМ месте и были сдержаннее в оценках....

Как-то так...

Каждый "хочет" быть на месте ДРУГОГО, но далеко НЕ КАЖДЫЙ готов к этому...