Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.12.25;
Скачать: CL | DM;

Вниз

Примеры кода, достойные орехов.   Найти похожие ветки 

 
Владислав ©   (2005-11-29 15:17) [0]

Нашел вот такой код в большом проекте.
Сохранено авторское форматирование кода. Комментарии мои.

//**********************************************************************************

// Процедура увеличивает длину строки S до Len и добавляет в конец строки S пробелы.

 procedure UpdateLength(var S: string; Len: integer);
 var
   I: integer;
 begin
   for I := Length(S) + 1 to Len do
     S := S + " ";
 end;

// Пример использования.
// Выравниваем длину строк S1, S2 и S3, добавляя в конец строк пробелы.

 if S1 > S2
   then MaxLen := Max(Length(S1), Length(S3))
   else MaxLen := Max(Length(S2), Length(S3));
 UpdateLength(S1, MaxLen);
 UpdateLength(S2, MaxLen);
 UpdateLength(S3, MaxLen);

//**********************************************************************************

// Ожидаем, пока пользователь не нажмет кнопку на немодальной форме

 while FProgress.ModalResult = mrNone do
   Application.ProcessMessages;

//**********************************************************************************

// Этот тип нам понадобится, чтобы добраться до protected свойства

type
 TThreadAccess = class(TBaseAsyncRunThread);

// Следующий код выполняет главный поток приложения.
// Здесь проверяется (я бы сказал, кто-то хотел, чтобы проверялось) завершился ли дополнительный поток.
// Свойство Terminated определено в TThread. Правда почему то protected.
// Для проверки этого свойства и понадобился класс TThreadAccess.
// Если Terminated = True, уничтожаем экземпляр класса, наследника TThread.
// Если же Terminated = False, убиваем поток на сервере баз данных.
// Процедуру Terminate при этом никто и не подумал вызвать.
// Справедливости ради, надо заметить, что этот код работал.
// Ни разу не было никаких исключений типа Access Violation,
// а то, что при этом убивался серверный процесс - особенности реализации...

     if TThreadAccess(FThreadList[I]).Terminated then
       TBaseAsyncRunThread(FThreadList[I]).Free
     else begin
       TBaseAsyncRunThread(FThreadList[I]).ClearNotify;
       KillServerProcess(TBaseAsyncRunThread(FThreadList[I]));

//**********************************************************************************

// Ничего необычного. Объявлен тип метода.

 TMonitorEventProc = procedure(Connection: TADOConnection; const Sql, ErrMsg: string;
   IsStart: Boolean; RecsAff: Integer) of object;

// Тоже ничего необычного. Глобальная переменная типа метод объекта.

 MonitorProc: TMonitorEventProc = nil;

// Проверяем, присвоен ли наш обработчик неких событий глобальной переменной.
// Если установлен, ничего не делаем, но событий ждем.
// А то, что у методов есть еще какая-то там TMethod.Data -
// пусть волнует тех, кто об этом знает.

 if @MonitorProc <> @TfmMonitor.MonitorEvent then
 begin
   MonitorProc := MonitorEvent;
 end;

//**********************************************************************************


У кого есть что-то подобное, чтобы поделиться?..

P.S.: Почему-то этот код вместо улыбки вызывает разочарование и уныние :(


 
Ega23 ©   (2005-11-29 15:21) [1]


function TfmMain.IncDay(const DateTime: TDateTime;  NumberOfDays: Integer): TDateTime;
{Функция предназначена для изменения даты (DateTime) путем добавления  количества дней (NumberOfDays). Значение NumberOfDays может быть отрицательным.}
var
 Y, M, D, CountDays: Word;
 N: Integer;
 Sign, NoBreak: Boolean;
begin
 Sign := NumberOfDays >= 0;
 DecodeDate(DateTime, Y, M, D);
 N := NumberOfDays;
 NoBreak := True;
 if Sign then   //Прибавить
 begin
   while(NoBreak) do
   begin //Количество дней в месяце
     CountDays := MonthDays[IsLeapYear(Y), M];
     if (N + D) <= CountDays then //Если в пределах данного месяца
     begin
       Inc(D, N);
       NoBreak := False;
     end
     else
     begin
       if M < 12 then
         Inc(M, 1)
       else
       begin
         M := 1;
         Inc(Y, 1);
       end;
       N := N - (CountDays - D);
       D := 0;
     end;
   end;
 end
 else  //Отнять
 begin
   N := -N;
   while(NoBreak) do
   begin
     if D > N then  //Если в пределах данного месяца
     begin
       Dec(D, N);
       NoBreak := False;
     end
     else
     begin
       if M > 1 then
         Dec(M, 1)
       else
       begin
         M := 12;
         Dec(Y, 1);
       end;
       //Количество дней в месяце
       CountDays := MonthDays[IsLeapYear(Y), M];
       N := N - D;
       D := CountDays;
     end;
   end;  
 end;
 Result := EncodeDate(Y, M, D);
 //Установить время из старой даты
 ReplaceTime(Result, DateTime);
end;


 
Джо ©   (2005-11-29 15:22) [2]


>  [1] Ega23 ©   (29.11.05 15:21)

8-()
Надеюсь, автора уже убили садистским способом или он все еще гуляет на свободе среди нас?!
:)


 
Ega23 ©   (2005-11-29 15:24) [3]


> Надеюсь, автора уже убили садистским способом или он все
> еще гуляет на свободе среди нас?!


IncDay - это классика! Собственно говоря, я из-за неё на delphimaster ходить начал. Кто-то из приятелей ссылку прислал, чтобы поржать.
Текст уже года 3 висит на стенке.  :о)


 
Nikolay M. ©   (2005-11-29 15:25) [4]


> Ega23 ©   (29.11.05 15:21) [1]
> Владислав ©   (29.11.05 15:17)  

Это все детский лепет.
Учу писать программы, дорого:
http://www.rsdn.ru/Forum/Message.aspx?mid=1320137&only=1


 
Igorek ©   (2005-11-29 15:27) [5]

Ну про банер мелкософта я уже писал..


 
Суслик ©   (2005-11-29 15:31) [6]

у меня полно такого, в основном собственной разработки.
работает 10й год, ну и слава богу :)

иногда бывают потуги отрефаторить чего-то.

но довести до конца времени нет, и, прямо скажем, резковыраженной необходимости.


 
Lamer@fools.ua ©   (2005-11-29 15:31) [7]

Шо-то у всех так длинно. Я попроще встречал (VB.NET):

Public Function DoSomething() As Boolean
   Dim retValue As Boolean

   " Ту шо-то считаем

   If retValue = True Then
       Return True
   Else
       Return False
   End if
End Function


 
Ega23 ©   (2005-11-29 15:34) [8]

If retValue = True Then
      Return True
  Else
    if retValue = False then
      Return False
  End if


:о)


 
Джо ©   (2005-11-29 15:34) [9]


>  [4] Nikolay M. ©   (29.11.05 15:25)

:))))
Под столом.


 
alex_*** ©   (2005-11-29 15:35) [10]

[7] это классика :) . Даже на собеседовании как-то попросили упростить что-то типа этого


 
Nikolay M. ©   (2005-11-29 15:39) [11]


> Джо ©   (29.11.05 15:34) [9]

Был там же по прочтении. Каменты рулят :)


 
Владислав ©   (2005-11-29 15:45) [12]

Таки вызвало улыбку :)
Нет худа без добра :)


 
Digitman ©   (2005-11-29 15:50) [13]

Вот такой код я имел "удовольствие" узреть в проекте одного "реального пацана", всеръез водившего (и по сей день водящего) за нос одного из солидных заказчиков в Московии:

if (tp=TClass($7C509300)) or (tp=TClass($7D73E190))  or (tp=TClass($7D73C270)) or (tp=TClass($775E98D8))
then ...

это даже не столько орех, сколько диверсия)


 
Джо ©   (2005-11-29 15:55) [14]


>
>  [13] Digitman ©   (29.11.05 15:50)

Жестоко.


 
Владислав ©   (2005-11-29 15:56) [15]


> это даже не столько орех, сколько диверсия)


Это уж точно диверсия!


 
pasha_golub ©   (2005-11-29 15:56) [16]


> Digitman ©   (29.11.05 15:50) [13]


А шо оно делать должно? Не понимаю я, к сожалению


 
Джо ©   (2005-11-29 15:57) [17]


> [13] Digitman ©   (29.11.05 15:50)

Он, надо полагать, ссылки менял после каждой модификации программы? Садомазо...


 
Ega23 ©   (2005-11-29 15:57) [18]


> if (tp=TClass($7C509300)) or (tp=TClass($7D73E190))  or
> (tp=TClass($7D73C270)) or (tp=TClass($775E98D8))
> then ...
>


А как оно работает????


 
Digitman ©   (2005-11-29 16:01) [19]

логика автора сего шедевра на редкость проста и убивает наповал (услышано прямо из его уст) - мол, у меня это работает, у заказчика - тоже, пока я якшаюсь с заказчиком - это мои проблемы, а после меня хоть потоп)


 
Суслик ©   (2005-11-29 16:01) [20]

Они еще спрашивают!
А сами орехи суют :)


 
Digitman ©   (2005-11-29 16:04) [21]


> Джо ©   (29.11.05 15:57) [17]


в том-то и дело, что не менял) ... до поры до времени ему просто везло и везет)


 
Digitman ©   (2005-11-29 16:07) [22]


> pasha_golub ©   (29.11.05 15:56) [16]


таким образом автор сего чуда программерской мысли пытается идентифицировать класс некоего своего объекта, сравнивая со ссылками на записи о классах в RTTI


 
Ega23 ©   (2005-11-29 16:07) [23]


> Они еще спрашивают!
> А сами орехи суют :)


В смысле, а где гарантия, что указатель только по этим четырём адресам будет?
Или всё-таки, шансы высоки?


 
Суслик ©   (2005-11-29 16:09) [24]

это может быть одно из средств защиты своего приложения :)
грубое, но все же.


 
Суслик ©   (2005-11-29 16:10) [25]


> В смысле, а где гарантия, что указатель только по этим четырём
> адресам будет?
> Или всё-таки, шансы высоки?

насколько я понимаю они грузятся в rtl.
Наверно (не проверял) можно заставить грузиться ее по одному адресу.


 
Суслик ©   (2005-11-29 16:10) [26]


> В смысле, а где гарантия, что указатель только по этим четырём
> адресам будет?
> Или всё-таки, шансы высоки?

насколько я понимаю они грузятся в rtl.
Наверно (не проверял) можно заставить грузиться ее по одному адресу.


 
msguns ©   (2005-11-29 16:11) [27]

>Ega23 ©   (29.11.05 15:57) [18]
>А как оно работает????

А никак. В смысле then никогда не наступает ;)


 
pasha_golub ©   (2005-11-29 16:11) [28]


> Суслик ©   (29.11.05 16:09) [24]
>
> это может быть одно из средств защиты своего приложения
> :)
> грубое, но все же.
>

Я тоже об этом подумал, но это пипец конечно :0)


 
Суслик ©   (2005-11-29 16:14) [29]

Пипец, конечно. Зато поддерживать твоею же программу будут звать всегда тебя.


 
Digitman ©   (2005-11-29 16:17) [30]


> msguns ©   (29.11.05 16:11) [27]


ну почему же ?

наступает) ... до той поры пока rtl от сеанса к сеансу грузится по одному и тому же (ожидаемому автором шедевра) адресу ... или до той поры пока версия rtl та же что и у автора ... тут удивительно другое - как у заказчика до сих пор это ружьё не выстрелило)


 
jack128 ©   (2005-11-29 16:21) [31]

Nikolay M. ©   (29.11.05 15:25) [4]
я даже могу сказать откуда этот код взялся у Валика. Ему он достался от дяди Борланда. см SysUtils.pas

По теме вот такой код видел:

raise TSomeException.Create(XXX);
DoSomething;


 
Суслик ©   (2005-11-29 16:22) [32]

Сергей, это адназначат защита :)


 
Digitman ©   (2005-11-29 16:27) [33]

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


{$IFDEF Digitman}
function IsInterface(obj: Pointer; const aGUID: TGUID): Boolean;
var
 Intf: IInterface;
begin
 Result := False;
 if Assigned(obj) then
   try
     Result := IUnknown(obj).QueryInterface(aGUID, Intf) = 0;
   except
   end;
end;
{$ENDIF}

..

if
{$IFDEF Digitman}
 IsInterface(Pointer(obj), IXMLNode)
{$ELSE}
 (tp=TClass($561A66)) or (tp=TClass($4fcd6a)) or (tp=TClass($4fcd76)) or (tp=TClass($50540A))
 or (tp=TClass($503ee2)) or (tp=TClass($503f5e)) or (tp=TClass($5B081A)) or (tp=TClass($504ACE))
 or (tp=TClass($503F82)) or (tp=TClass($503F72)) or (tp=TClass($504AB6)) or (tp=TClass($504B3E))
{$ENDIF}
then begin
 tnode:=ixmlnode(pointer(obj));
 with tnode.childnodes do for i1:=0 to count-1 do
   process(pointer(nodes[i1]),adv1,adv2);
end else

if
{$IFDEF Digitman}
 IsInterface(Pointer(obj), ihtmlelement)
{$ELSE}
 (tp=TClass($7C509300)) or (tp=TClass($7D73E190)) or (tp=TClass($7D73C270))
   or (tp=TClass($775e98d8))
{$ENDIF}
then begin
 hnode:=ihtmlelement(pointer(obj));

....


а защитой тут и не пахнет) ... тут дурью отдает изрядно)


 
Владислав ©   (2005-11-29 16:27) [34]


> raise TSomeException.Create(XXX);
> DoSomething;


Своего рода, как бы так выразиться, far exit? :)
Выход из нескольких процедур? :)


 
Ega23 ©   (2005-11-29 16:31) [35]


> Наверно (не проверял) можно заставить грузиться ее по одному
> адресу.


Вот если можно заставить грузиться по одному адресу, то действительно как средство защиты можно рассматривать. Тогда всё понятно.
Только я первый раз про такое слышу.
Собственно, поэтому и спросил...


 
Суслик ©   (2005-11-29 16:35) [36]

Да это я предположил только :)


 
Alkid ©   (2005-11-29 16:36) [37]


> Вот если можно заставить грузиться по одному адресу, то
> действительно как средство защиты можно рассматривать. Тогда
> всё понятно.
> Только я первый раз про такое слышу.
> Собственно, поэтому и спросил...

В принципе каждый модуль (в том числе и .exe) имеет заданный в PE файле базовый адрес. И при расположении сегментов модуля этот базовый адрес используется как точка отсчёта. Можно ли этот факт использовать для защиты - ХЗ.


 
Владислав ©   (2005-11-29 16:42) [38]

Вот же блин!

// Возвращает строку из символов Char длиной Count.
// Одно название модуля говорит за себя!
// Модуль назвается SoStrUtils.

function Chars(C: Char; Count: Integer): string;
var Index: LongInt;
begin
 Result := EmptyStr;
 for Index := 1 to Count do Result := Result + C;
end;


 
Суслик ©   (2005-11-29 16:43) [39]


> function IsInterface(obj: Pointer; const aGUID: TGUID):
> Boolean;
> var
>  Intf: IInterface;
> begin
>  Result := False;
>  if Assigned(obj) then
>    try
>      Result := IUnknown(obj).QueryInterface(aGUID, Intf)
> = 0;
>    except
>    end;
> end;


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


 
jack128 ©   (2005-11-29 16:47) [40]

Суслик ©   (29.11.05 16:43) [39]
Ну в общем то да. И такое было  
var
 p: pointer;
begin
 ...
 try
   f := TObject(P) is TSomeObject;
 except
   f := False;
 end;
 if f then
   ...
end;

Хотя вероятность некоректных действий тут практически нулевая, но тем не менее..


 
Суслик ©   (2005-11-29 16:54) [41]

2[40]

Да как сказать нулевая.

Пример.

type
  i = interface
     procedure SomeMethod();
  end;

  c = class(..., i) // подсчет ссылок отключен!
     procedure SomeMethod();
  end;

var
  o: c;
begin
  o := c.create();
  (c as i).SomeMethod.
  o.free();
end; // тут может быть очень суровый av

А все потому, что дельфи вызывает _release у неизвестно чего.

Я эту ошибку в свое время искал очень долго. Более того, эффект сказывался далеко за пределами данного кода.


 
Игорь Шевченко ©   (2005-11-29 16:54) [42]

Владислав ©   (29.11.05 16:42) [38]

"Важной частью пропагандируемого мною стиля программирования является
разложение сложных процедур на небольшие методы. Если делать это неправильно,
то придется изрядно помучиться, выясняя, что же делают эти маленькие методы.
Избежать таких мучений помогает назначение методам хороших имен. Методам
следует давать имена, раскрывающие их назначение. Хороший способ для этого -
представить себе, каким должен быть комментарий к методу, и преобразовать
этот комментарий в имя метода.
Жизнь такова, что удачное имя может не сразу придти в голову. В подобной
ситуации может возникнуть соблазн бросить это занятие - в конце концов,
не в имени счастье. Это вас соблазняет бес, не слушайте его. Если вы видите,
что у метода плохое имя, обязательно измените его. Помните, что ваш код
в первую очередь предназначен человеку, а только потом - компьютеру.
Человеку нужны хорошие имена. Вспомните, сколько времени вы потратили,
пытаясь что-то сделать, и насколько проще было бы, окажись у пары методов
более удачные имена. Создание хороших имен - это мастерство, требующее
практики; совершенствование этого мастерства - ключ к превращению
в действительно искусного программиста.
То же справедливо и в отношении других элементов сигнатуры метода.
Если переупорядочивание параметров проясняет суть - выполните его."

(с) Мартин Фаулер


 
Суслик ©   (2005-11-29 16:55) [43]

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


 
jack128 ©   (2005-11-29 16:56) [44]

Суслик ©   (29.11.05 16:54) [41]
Помниться разовор на эту тему уже был ;) Раз не используешь подсчет ссылок, то все огрехи на тебе, а не на борланде ;)


 
Суслик ©   (2005-11-29 16:58) [45]

дело не к том, кто виноват.
а в том, что нельзя вызывать метод у неизветно чего :)
я только это утверждаю


 
Alkid ©   (2005-11-29 17:02) [46]

Типа реплика из аудитории, не дыша внимающей беседе: а это вообще правильно, что наследник от TObject приводится к Pointer`у? Вот уж сколько лет я программирую, но таких перлов делать не доводилось.
Так что этот спор, имхо, из разряда "как сделать из полной фигни что-то нормальное". Может не стоит изначально фигню писать?


 
Джо ©   (2005-11-29 17:04) [47]

[46] Alkid ©   (29.11.05 17:02)
>  а это вообще правильно, что наследник от TObject приводится
> к Pointer`у?

Вполне нормально, имхо. А вот наоборот - уже можно и огрести.


 
Ega23 ©   (2005-11-29 17:07) [48]


> Типа реплика из аудитории, не дыша внимающей беседе: а это
> вообще правильно, что наследник от TObject приводится к
> Pointer`у?


В TList все элемены к Pointer"у приводятся... И не только наследники TObject...  :о)


 
Суслик ©   (2005-11-29 17:08) [49]

Ну огрести это слишком.
Взять тот же TList.
Почему бы в него не засунуть TObject?


 
Alkid ©   (2005-11-29 17:09) [50]


> Вполне нормально, имхо. А вот наоборот - уже можно и огрести.

Нет, то, что операция приведения Pointer(TObject) легальна со всех точек зрения, кроме здравого смысла, я согласен. Но именно с точки зрения здравого смысла мы загоняем себя в яму из которой выбираемся проявляя чудеса изобретательности (очень уж это в нашем менталитете сильно ;) )
Можно не Pointer а тот самый TObject сделать? Или сделать интерфейс и передавать через него. Вообще, если нет возможности передать значение типа TObject, то скоее всего мы имеем дело с каким-то смешанным кодом, где два дельфёвых куска программы взаимодейстуют через ж... т.е. недельфёвый кусок кода, который дельфёвые типы не разумеет. В этом случае надо использовать интерфейсы, для того они и сделаны.


 
Ega23 ©   (2005-11-29 17:11) [51]


> Можно не Pointer а тот самый TObject сделать?


А для этого существует не TList, а TObjectList...   :о)


 
Владислав ©   (2005-11-29 17:14) [52]


> Игорь Шевченко ©   (29.11.05 16:54) [42]


Игорь, а к чему здесь это было процитировано?


 
Alkid ©   (2005-11-29 17:16) [53]


> А для этого существует не TList, а TObjectList...   :о)

И вообще, хорошая практика - порождение специализированных классов для объектов определённого типа (наследников от определённого класса). При этом используемый класс списка (тот же TObjectList) лучше инкапсулировать, что бы кто-нибудь не положил в него что-то лишнее, не приводимое к нашему классу. Тогда все эти проблемы типа "блин, вот Pointer, а как узнать, что в нём лежит?!" отпадают сразу.


 
Гость1   (2005-11-29 17:18) [54]


> А для этого существует не TList, а TObjectList...   :о)

TThreadList - ? Есть объектные аналоги?


> Alkid ©   (29.11.05 17:09) [50]

А как быть с TTreeView? Конкретно, с TTreeNode.Data кода нужно в узлы объекты помещать?


 
Джо ©   (2005-11-29 17:18) [55]


>  [53] Alkid ©   (29.11.05 17:16)
> [50] Alkid ©   (29.11.05 17:09)

Согласен.


 
Ega23 ©   (2005-11-29 17:21) [56]


> И вообще, хорошая практика - порождение специализированных
> классов для объектов определённого типа (наследников от
> определённого класса). При этом используемый класс списка
> (тот же TObjectList) лучше инкапсулировать, что бы кто-нибудь
> не положил в него что-то лишнее, не приводимое к нашему
> классу. Тогда все эти проблемы типа "блин, вот Pointer,
> а как узнать, что в нём лежит?!" отпадают сразу.


А кто с этим спорит?


 
Игорь Шевченко ©   (2005-11-29 17:22) [57]

Владислав ©   (29.11.05 17:14) [52]


> Игорь, а к чему здесь это было процитировано?


А к тому, что метод называется Chars а делает вовсе не то.


 
Владислав ©   (2005-11-29 17:29) [58]


> Игорь Шевченко ©   (29.11.05 17:22) [57]
>
> А к тому, что метод называется Chars а делает вовсе не то.
>


Хе-хе :)
Видать я к таким выкидонам уже привык на новой работе, что меня это уже не напрягает.

Я когда переписывал код с вызовом этой функции (у нас новая версия продукта пишется), новый код у меня не сразу скомпилировался. Так я просто пошел к реализации функции (это уже обыденное дело). Заменил вызов Chars() на StringOfChar().

Мартин Фаулер может спать спокойно?.. :)


 
Alkid ©   (2005-11-29 17:29) [59]


> > А для этого существует не TList, а TObjectList...   :о)
>
> TThreadList - ? Есть объектные аналоги?
  А самому сделать слабо? Я, например, написал однажды потокозащищённый класс для объектов, и для строк и для ещё чего-то. Уже три года пользуюсь и не парюсь.

> > Alkid ©   (29.11.05 17:09) [50]
>
> А как быть с TTreeView? Конкретно, с TTreeNode.Data кода
> нужно в узлы объекты помещать?

 Вот тут идея хромает, ибо нет возможности самому делать наследников от TTreeNode пихать в них произвольные данные и пихать их в дерево. Это явный недостаток класса TTreeNodes. Приходится извращаться. Как правило я просто инкапсулировал TTreeView целиком, что бы предотвратить несанкционированный доступ к его данных как к Pointer`ам. Это гарантировало мне, что в Data лежит что-то вполне конкретное и я могу приводить его обратно к нужному типу без проблем. А вообще я когда только можно пользуюсь собственными классами для обслуживания древесных структур в памяти.


 
Alkid ©   (2005-11-29 17:33) [60]

Кстати о TTreeView, там есть protected функция CreateNode, выступающая в роли фабрики класса узлов дерева. Функцию можно перегрузить, что бы она штамповала не TTreeNode, а наследников от него, в которые можно определить любые поля по вкусу. Так что не всё так пасмурно на древесном фронте :)


 
Гость1   (2005-11-29 17:43) [61]


> Вот тут идея хромает, ибо нет возможности самому делать
> наследников от TTreeNode пихать в них произвольные данные
> и пихать их в дерево.

Не, тут все путем,
есть OnCreateNodeClass, где в зависимости от условий указываешь класс создаваемого узла.

Я знаю, что все надо переписывать в соответствии с правилами, но тут ключевое слово "лень", которое маскируется словом "целесообразность". :)

Про потокозащищенный объектный список я спросил лишь из-за того, что может я плохо хелп читал и он реализован. :)


 
Alkid ©   (2005-11-29 17:58) [62]


> Не, тут все путем,
> есть OnCreateNodeClass, где в зависимости от условий указываешь
> класс создаваемого узла.
  Ну вообще всё круто :)
>
> Я знаю, что все надо переписывать в соответствии с правилами,
>  но тут ключевое слово "лень", которое маскируется словом
> "целесообразность". :)
   Это дело понятное :)
>
> Про потокозащищенный объектный список я спросил лишь из-
> за того, что может я плохо хелп читал и он реализован. :
> )

 Нет, в хелпе и правда такого зверя нет. Я и про TThreadList не слышал раньше, если честно. А потокозащищённые контейнеры делал сам, вооружившись TCriticalSection :-)


 
Суслик ©   (2005-11-29 21:06) [63]

Up.

Очень хотелось бы услышать комментарии digitman"а по поводу его кода [33] и моих возражений по поводу того, что нельзя вызывать методы у неизвестно чего.

Данный интерес вызван тем, что вполне возможно, что я ошибаюсь и можно вызывать.
Чудеса бывают. Например, я видел код, в котором, есть self.free в середине метода, но написано все корректно - после free нет обращений, к полям self - только к стековым переменным (т.е. локальным) или глобальным. В итоге все работает корректно.

Может бють и здесь есть какая-то неучтенная мною хитрость.


 
имя   (2005-11-29 21:39) [64]

Удалено модератором


 
jack128 ©   (2005-11-29 22:00) [65]

Борис Березовский   (29.11.05 21:39) [64]
PostQuitMessage(Msg.wParam);

Зачем это??  А так, нормальная функция, если писать на API. Хотя можно и лудше если вместо Sleep(StepMsgUpdate); написать
if MsgWaitForMultipleObjects(0, nil^, False, I - GetTickCount, QS_ALLINPUT) = WAIT_TIMEOUT then
     Exit;


 
jack128 ©   (2005-11-29 22:16) [66]

Суслик ©   (29.11.05 21:06) [63]
Например, я видел код, в котором, есть self.free в середине метода, но написано все корректно - после free нет обращений, к полям self - только к стековым переменным (т.е. локальным) или глобальным. В итоге все работает корректно.

А это абсолютно корректный(по крайней мере с технической точки зрения) подход. Насчет кода Дигитмена - да, он опасен. Он ничем не отличается от такого:
var
 P: TProcedure;
begin
 P := TProcedure(Pointer(Integer(Random(MaxInt))));
 P;
end;
Проблема в том, что мы вообще неизвестно какой код вызываем..


 
vuk ©   (2005-11-29 22:27) [67]

to jack128 ©   (29.11.05 22:16) [66]:
>Насчет кода Дигитмена - да, он опасен.
В принципе да, но там нам остается неизвестным окружение, в котором код работает. Если в obj гарантировано будет интерфейсная ссылка, то все нормально.


 
jack128 ©   (2005-11-29 22:29) [68]

vuk ©   (29.11.05 22:27) [67]
Если в obj гарантировано будет интерфейсная ссылка,

То всю эту функцию можно переписать как
Result := Assigned(P)  ;)


 
vuk ©   (2005-11-29 22:32) [69]

to jack128 ©   (29.11.05 22:29) [68]:
>То всю эту функцию можно переписать как
Не совсем. Если внимательно посмотрите, то там ветвление и проверяются два разных интерфейса.


 
jack128 ©   (2005-11-29 22:36) [70]

Да, не обратил внимание, сорри.


 
Uncle Archi ©   (2005-11-29 23:08) [71]

jack128 ©   (29.11.05 22:16) [66]
Этот код всего навсего дает Accsess Voliation в одном и том же адресе, или, если поставить RandomIze, то в разных.. )))


 
evvcom ©   (2005-11-30 08:31) [72]


> Alkid ©   (29.11.05 16:36) [37]
>
> > Вот если можно заставить грузиться по одному адресу, то
>
> > действительно как средство защиты можно рассматривать.
>  Тогда
> > всё понятно.
> > Только я первый раз про такое слышу.
> > Собственно, поэтому и спросил...
>
> В принципе каждый модуль (в том числе и .exe) имеет заданный
> в PE файле базовый адрес. И при расположении сегментов модуля
> этот базовый адрес используется как точка отсчёта. Можно
> ли этот факт использовать для защиты - ХЗ.

Базовый адрес имеется и загрузчик туда и загрузит, если место еще не занято. Но использовать этот факт нельзя, потому как нет никакой гарантии, что эти адреса к моменту загрузки действительно будут свободны и загрузчик не переместит вследствие этого модуль в другие адреса.


> Как правило я просто инкапсулировал TTreeView целиком, что
> бы предотвратить несанкционированный доступ к его данных
> как к Pointer`ам. Это гарантировало мне, что в Data лежит
> что-то вполне конкретное

Да нифига не гарантирует. Ну есть у тебя TMyTreeNode.Data: TObject, а я такой "извращенец" беру и делаю:
var
 MyIntVar: Integer;
begin
 MyTreeNode.Data := TObject(@MyIntVar);
 // Да хоть и так:
 MyTreeNode.Data := TObject(Pointer(MyIntVar));

И все! Все специально писанное инкапсулирование, "гарантирующее" абсолютную корректность коту под хвост. Просто программист, работающий с указателями и преобразованиями типов, должен четко себе представлять, что он делает, и подобные, потенциально опасные участки кода подробно комментировать (для потомков). Мое имхо.


 
Alkid ©   (2005-11-30 10:32) [73]


> Да нифига не гарантирует. Ну есть у тебя TMyTreeNode.Data:
>  TObject, а я такой "извращенец" беру и делаю:
> var
>  MyIntVar: Integer;
> begin
>  MyTreeNode.Data := TObject(@MyIntVar);
>  // Да хоть и так:
>  MyTreeNode.Data := TObject(Pointer(MyIntVar));
>
> И все! Все специально писанное инкапсулирование, "гарантирующее"
> абсолютную корректность коту под хвост. Просто программист,
>  работающий с указателями и преобразованиями типов, должен
> четко себе представлять, что он делает, и подобные, потенциально
> опасные участки кода подробно комментировать (для потомков).
>  Мое имхо.

Ну, если программист хочет разложить себе на будущее грабелек, что бы по ним потом увлекательно погулять, то он может делать такие вещи. От извращенцев и просто некомпетентных программистов ни один код не застрахован (хотя уже в Java & .NET такие вещи не пройдут).

Здесь просто мы на самом деле затронули более общую проблему:
Программист должен делать свои классы такими, что бы количество потенциальных граблей, на которые можно наступить неправильным применением его кода, было минимальным и грабли эти были наиболее очевидны. По этому речь идёт не о том, что я написал гениальный класс, с которым и полный дебил напишет неглючащую программу. Речь идёт о том, что я написал более безопасный класс, так как там вещи называются своими именами: TObject называется TObject`ом, а не Pointer`ом. А значит на будущее создал себе меньше граблей  :-)


 
TUser ©   (2005-11-30 11:10) [74]

Я уже приводил пример. Как поддерживается - не в курсе.
http://monkey.belozersky.msu.su/~evgeniy/tokens.c

ЗЫ. А что "такого" в первом и третьем примере из топика?


 
Alkid ©   (2005-11-30 11:21) [75]


> http://monkey.belozersky.msu.su/~evgeniy/tokens.c

ЗачОт! Код сколь гениальный, столь и нехороший в плане поддержки этого дела. Единственное оправдание такому коду - это если бы он был автоматически сгенерирован :)

Вообще в бытность C++ программистом (сейчас я по долгу службы переполз на Delphi, а "для души" программирую на C# в C#Builder`e) я тоже иногда вот так изголялся и писал извращённый код. В этом смысле C++ богат возможностями для экономии битов и тактов. Но потом пришёл к выводу, что начиная с программ уже среднего размера читаемость кода и его логическая прозрачность гораздо более важны, чем лихость такая программирования.


 
Владислав ©   (2005-11-30 11:22) [76]

Э-э-э... В первом и третьем посте?


 
jack128 ©   (2005-11-30 11:26) [77]

Владислав ©   (30.11.05 11:22) [76]
третьем посте

не посте, а примере. Тот что Коля М привел. Я уже сказал, что это код Борланда.


 
iZEN ©   (2005-11-30 14:59) [78]

Вот ещё:

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class GaugeMidlet extends MIDlet implements CommandListener {
   private Display display;
   private Command CMD_EXIT = new Command("EXIT", Command.EXIT, 1);
   private Command CMD_OK = new Command("OK", Command.OK, 1);
   private Form inputForm;
   private TextField nameText;
   private Form gaugeForm;
   private Gauge searchGauge;
   public GaugeMidlet() {
       display = Display.getDisplay(this);
       inputForm = new Form("Параметры");
       nameText = new TextField("Фамилия", "", 20, TextField.ANY);
       inputForm.append(nameText);
       inputForm.addCommand(CMD_EXIT);
       inputForm.addCommand(CMD_OK);
       inputForm.setCommandListener(this);
   }
   public void startApp() {
       display.setCurrent(inputForm);
   }
   public void pauseApp() {}
   public void destroyApp(boolean unconditional) {}
   public void commandAction(Command command, Displayable screen) {
       if (command == CMD_EXIT) {
           destroyApp(false);
           notifyDestroyed();
       }
       if (command == CMD_OK) {
           gaugeForm = new Form("ищет...");
           searchGauge = new Gauge("", false, 20, 1);
           gaugeForm.append(searchGauge);
           gaugeForm.addCommand(CMD_EXIT);
           gaugeForm.setCommandListener(this);
           display.setCurrent(gaugeForm);
           searchGauge.setValue(0);
           for (int i = 0; i < 10000000; i++) {}
           searchGauge.setValue(10);
           for (int i = 0; i < 10000000; i++) {}
           searchGauge.setValue(20);
       }
   }
}

В общем, я офигеваю от такого качества знаний кодеров. Что же там в J2ME-играх творится, одним им известно...


 
Суслик ©   (2005-11-30 15:10) [79]

2iZEN

окромя задержки через for вроде все приемлемо
наверное детали какие-то я упустил...


 
iZEN ©   (2005-11-30 20:51) [80]


> Суслик ©   (30.11.05 15:10) [79]

А если подумать хорошенько. То код выполняться будет не так.
searchGauge.setValue(...); не асинхронный, а это значит, что в обработчике commandAction мы получим не то что конкретный зависон на циклах, но и необновление компонента searchGauge.
По окончании работы commandAction, конечно же, searchGauge будет иметь значение 20.
Здесь по-хорошему нужна отдельная нить (что я и реализовал в нескольких вариантах, включая разработку отдельного небольшого/независимого от J2ME фреймворка. На будущее...).


 
Ученик чародея ©   (2005-12-01 04:16) [81]

procedure mura(var mura:mur;graph:algoritm);
label 1,2;
var
xored:byte;
i,j:byte;
Last_V:byte;
Last_i:byte;
Max_V:byte;
Code_V:Vector;
N_X:byte;
X:Vector;
X_Val:Vector;
begin
for i:=1 to graph.N_V do   {number peroxodow}
for j:=1 to graph.N_V do
if graph.links[i,j]=1 then
mura.N_max:=mura.N_max+1;
mura.N_Max:=mura.N_Max-graph.N_X;

{recode операторные вершины, условные вершины}
Last_V:=0;
for i:=1 to graph.N_V do
if (Graph.X_link[i]=0) then
begin
Last_V:=Last_V+1;
Code_V[i]:=Last_V;
end
else
Code_V[i]:=0;
Max_V:=Last_V;

{tablicha perehodow}
while mura.N_Last<>mura.N_Max do
begin
for i:=1 to graph.N_V do
begin
N_X:=0;
last_V:=i;
find_1(Graph,i,j);
2:
if j<>0 then
           if graph.X_Link[j]=0 then
                                begin
                                   mura.N_last:=mura.N_last+1;
                                   mura.dugi[mura.N_last].N_Vershini:=Last_V;
                                   mura.dugi[mura.N_last].N_Dir:=j;
                                   mura.dugi[mura.N_last].N_X:=N_X;
                                   mura.dugi[mura.N_last].X:=X;
                                   mura.dugi[mura.N_last].X_val:=X_Val;
                                   mura.dugi[mura.N_last].N_Y:=graph.N_Y;
                                   mura.dugi[mura.N_last].Y:=Graph.Y_Value[j{Last_V}];
                                   Del_1(Graph,i);
                                   goto 1;
                                end
           else
           begin
                last_i:=i;
                i:=j;
                N_X:=N_X+1;
                X[N_X]:=Graph.X_Link[i];
                find_1(Graph,i,j);

                if j=0 then
                begin
                del_1(graph,last_i);
                goto 1;
                end;

                X_Val[N_X]:=Graph.X_Value[i,j];
                goto 2;
           end;

end;
1:
end;

{transete to binary form}
for i:=1 to mura.N_Max do
begin
mura.dugi[i].N_Vershini:=code_V[mura.dugi[i].N_Vershini]-1;
mura.dugi[i].N_dir:=code_V[mura.dugi[i].N_dir]-1;

if mura.dugi[i].N_Vershini=Max_V-1 then
mura.dugi[i].N_Vershini:=0;

if mura.dugi[i].N_Dir=Max_V-1 then
mura.dugi[i].N_Dir:=0;
end;
{Max trigers}
Max_V:=Max_v-1;
mura.n_trig:=trunc(ln(Max_V)/ln(2)+1);

{trigers}
for i:=1 to mura.N_max do
begin

if mura.rs=1 then
begin
mura.dugi[i].S:=mura.dugi[i].N_dir;
xored:=mura.dugi[i].N_dir;
asm
mov al,xored
not al
mov xored,al
end;
mura.dugi[i].R:=xored;
end;

if mura.jk=1 then
begin
mura.dugi[i].K:=mura.dugi[i].N_dir;
xored:=mura.dugi[i].N_dir;
asm
mov al,xored
not al
mov xored,al
end;
mura.dugi[i].J:=xored;
end;

if mura.D=1 then
begin
mura.dugi[i].D:=mura.dugi[i].N_dir;
end;
end;

end;


 
Fay ©   (2005-12-01 04:34) [82]

Дословно не помню, но такой вот код выдал один мой бывший коллега, сказав "Мне так удобнее" (он про все свои перлы говорил такое):

case с of
 "0" : n := 0;
 "1" : n := 1;
 "2" : n := 2;
 "3" : n := 3;
 "4" : n := 4;
 "5" : n := 5;
 "6" : n := 6;
 "7" : n := 7;
 "8" : n := 8;
 "9" : n := 9;
end;


Ему-то м.б. и удобно, а я 2 минуты всматривался - искал нетривиальность 8)


 
Владислав ©   (2005-12-01 08:40) [83]


> Fay ©   (01.12.05 04:34) [82]


У нас так класс объектов проверяется :о) Знать бы, кому руки отрывать.


 
Piero   (2005-12-01 18:14) [84]

А видели когда нибудь Dfm файл на 40 000 строк, причем на форме почти все компаненты визуальные - вообще ничего найти нельзя
а более 1000 глобальных переменных, и все функции без параметров,... да это детский лепет , по сравнению с тем, что это чучуло вытворяет, с которым я работаю

все печатать не буду
комментариев = 0

var
 MainForm     : TMainForm;
 PPil         : TParamPil;
 PNav         : TParamNav;
 PBP,PBPASP   : TParamBP;
 TWP          : RecM;
 Marsh        : file of RecM;
 NavP         : RecN;
 fNav         : file of RecN;
 fPRG         : file of RecPR;
 pPRG         : RecPR;
 IndAM        : boolean;  
 IndNM        : boolean;  
 IndEM        : boolean;  
 IndWrt       : boolean;  
 IndOTI       : boolean;  
 ImPVO        : boolean;
 IndDSF       : boolean;
 IndFE        : boolean;  
 ReadAF       : boolean;
 ChASP        : boolean;
 IndLookAM    : boolean;
 isNew,IndNav,MULT,AOA: boolean;
 EPM,PPM,PVO,TIM,mtwM: boolean;
 IndDT,IndAb,indVIZ: boolean;
 PointC       : boolean;
 IndSP        : boolean;
 IndRSDNb     : boolean;
 SaveM        : boolean;
 isChDS       : boolean;
 dLUR         : boolean;  
 Marsh10      : boolean;
 IndESC       : boolean;
 isMTR        : boolean;  
 isPRGM       : boolean;
 isCFP        : boolean;
 isPntM       : boolean;
 tlo          : TLocateOptions;
 RegimN       : RegName;
 Pbord: PntC;
 CPT: real;
 CountMP,CodeO,NumP,TipMP,RegPVO,RazvN,StHr,Hmax,Hmin,
 IndFT,NZon,NReg,NCel,NFin,KFmn,KLgr,KLmn,Hkr,HkrL,  
 DlnFT,FR,HFT,VFT,Svet1,Uvet1,NumD,DelTim,CountL,ModeW,
 Hasp,Vasp,kodF,NonEr,CntAC,NumAF,MapStop,MK,Mskl,
 Hkta,HktaF,HktaL,Hnt,Hpb,NumB,PPMT,CodPB,PPMTPB,IndCRZ,
 NumOCP,CodeC,CodeOCP,Nocp,Hs,Hf,NumAS,numS,Vs,Vf,ResQ: integer;
 Xmrs,Ymrs,Bc,Lc,KFgr,KRlnd,BPM1,LPM1,BPM2,LPM2,Bfly,Lfly,Blnd,Llnd,
 Bpb,Lpb,Az,Dln,Vinos,Bobj,Lobj,Fmin,Lmin,Fmax,Lmax,BRl,LRl,
 dt1_3,dt2_3,dt3_3,dt4_3,dt1_10,dt2_10,Bocp,Locp,Bor,Lor: float;
 NUser,PWord,PasW1,PasW2,PasW3,NamAP,NamNav,NamPodv,NamPB,
 NamRegion,NamBPM,NamEPM,NamM,NAfl,NamLnk,comm,Cword,NamFAS,Tnv1: string;
 BordC: file of PntC;
 fMTW: file of MTWH;
 hMTW: MTWH;
 fChH: file of pChH;
 rChH: pChH;
 fChV: file of pChV;
 rChV: pChV;
//  MapC: TUsMap;
 Lb: LongBool;
 InfO,ComQ: TextFile;
 MasNumP,MasPC: array[1..31]of integer;
 MasNP324: array[1..9]of string;
 MasNNP324: array[1..9]of integer;
 Mas6: array[1..2,1..3]of integer;
 DecSep: Char;
 Fdat: file;
 Rec: TSearchRec;
 RecAS: STRAS;
 PARM: MTRBUILDPARM;

можно и кода кусок показать вам


 
Игорь Шевченко ©   (2005-12-01 18:19) [85]

Piero   (01.12.05 18:14) [84]

Человек учился на Фортране программировать ? Просто интересно...


 
iZEN_   (2005-12-01 18:21) [86]


> Piero   (01.12.05 18:14) [84]

Похоже на машинный декомпиленный код, который был перед этим сурово обфускачен. ;))


 
Uncle Archi ©   (2005-12-01 18:29) [87]

Это так, кусочек. человек сдавал курсовик.

IF (PrGomory="Y") OR (PrGomory="y") THEN PrGomory:="Y" ELSE PrGomory:="N";


И ещё из той же программы
ZN:
IF (Fm<>1) AND (Fm<>2) THEN
                        BEGIN
                         WRITELN("Нерпавильный ввод");GOTO ZN;
                        END;

Ну это так, пример использования Goto, когда можно без него.


 
Piero   (2005-12-01 18:32) [88]

Да с фортраном угадал


 
Игорь Шевченко ©   (2005-12-01 18:36) [89]

Piero   (01.12.05 18:32) [88]

Вторая попытка - человек в оборонке работал ?


 
Antonn ©   (2005-12-01 18:42) [90]

открыл один из своих проектов, когда еще только начинал и ужаснулся:
tmp_max:=trunc(now)-encodedate(1,1,2)+ encodedate(1,1,1);
tmp_max - TDateTime, нужно было получить дату днем раньше... ужас просто, нет бы IncDay использовать:)


 
PVOzerski ©   (2005-12-01 18:46) [91]

2Игорь Шевченко:
Третья попытка - этого человека зовут <Нужное вставить> :)


 
TUser ©   (2005-12-01 19:37) [92]


> Э-э-э... В первом и третьем посте?

Примеры из поста [0]. Очень хочу узнать где там ошибка. Сам примерно так пишу - что тут не правильно?


 
Владислав ©   (2005-12-02 08:26) [93]


> Примеры из поста [0]. Очень хочу узнать где там ошибка.
> Сам примерно так пишу - что тут не правильно?


Может это не понятно без контекста, конечно...

В процедуре procedure UpdateLength(var S: string; Len: integer);
кроме того, что реалок строки происходит N-ное количество раз, мне бы, например, еще и лениво было бы определять количество итераций цикла. Проще уж было бы сложить две строчки, исходную и пробельную. Разве нет?

В while FProgress.ModalResult = mrNone do Application.ProcessMessages;
Процессор бесполезно загружается в пустом цикле. Другие приложения начинают медленней работать.

В
if TThreadAccess(FThreadList[I]).Terminated then
 TBaseAsyncRunThread(FThreadList[I]).Free

Метод Terminate поточного класса в коде нигде не вызывался. В поточной функции свойство Terminated не проверялось. А приведенный кусок кода выполнялся в главном потоке приложения.

В if @MonitorProc <> @TfmMonitor.MonitorEvent then
Сравниваются 4 байта, т.е. только указатель на процедуру, а нужно еще сравнивать указатель на экземпляр класса, чей метод сравнивается.


 
Владислав ©   (2005-12-02 08:29) [94]

Впрочем, за пример 2 из поста [0] я уже не переживаю. Автор добавил Sleep(50) перед Application.ProcessMessages; :о)


 
TUser ©   (2005-12-02 08:37) [95]


> В процедуре procedure UpdateLength(var S: string; Len: integer);
>  
> кроме того, что реалок строки происходит N-ное количество
> раз, мне бы, например, еще и лениво было бы определять количество
> итераций цикла. Проще уж было бы сложить две строчки, исходную
> и пробельную. Разве нет?

Не факт. Такой код нормально читается. Если это сделано не в каком-то критичном по скорости месте (а обычно всякие такие строковые штуки нужны при выводе результата, что никак не критично в смысле скорости) - тогда нормальный код. У меня такие примерно функции работают в нескольких программах. Может это и не эталон.

> В
> if TThreadAccess(FThreadList[I]).Terminated then
>  TBaseAsyncRunThread(FThreadList[I]).Free
> Метод Terminate поточного класса в коде нигде не вызывался.
>  В поточной функции свойство Terminated не проверялось.
> А приведенный кусок кода выполнялся в главном потоке приложения.
>

Метод Terminate мог быть вызван в другом потоке. А то, что он в коде нигде не вызывался - из приведенного примера поонять нельзя, поэтому и возникают сомнения с ореховости. А даже если он нигде и не вызывается, то можно предположить, что автор кода думал о будущем - вдруг в появятся дополнительные потоки. Хотя, наверное, проще выставить FreeOnTerminare, но может быть и так надо - трудно сказать, что код не правильный, без точного знания того, что за задача решалась

Про другие примеры вопорсов нет. За разьяснения - спасибо..


 
Lamer@fools.ua ©   (2005-12-02 09:07) [96]

>процедуре procedure UpdateLength(var S: string; Len: integer);
... реалок строки происходит N-ное количество раз


Поддерживаю. К тому же название функции не соотвествует выполняемым ею действиям. Я бы переписал как-то так:
procedure ExpandWithSpaces(var S: String; const NewLength: Integer);
var
 OldLength: Integer;
begin
 OldLength := Length(S);
 if NewLength > OldLength then
 begin
   SetLength(S, NewLength);
   FillChar(S[OldLength + 1], NewLength - OldLength, #32);
 end;
end;


Или даже так:
function ExpandWithSpaces(const S: String; const NewLength: Integer): String;
var
 OldLength: Integer;
begin
 Result := S;
 OldLength := Length(Result);
 if NewLength > OldLength then
 begin
   SetLength(Result, NewLength);
   FillChar(Result[OldLength + 1], NewLength - OldLength, #32);
 end;
end;


 
wal ©   (2005-12-02 09:12) [97]

Незнаю, достойно ореха или нет, но вчера написал такое:

var
 ExReturnCheck: boolean;
begin
...
   case ExReturnCheck of
     False: CashDriver.AddJob(cjPrintCheck, CashCheck, CheckPrinted);
     True: begin
              ...
             end;
   end;
...
end;
Мне, почему-то так красивее показалось, чем if-then-else. Сам не знаю почему.


 
Lamer@fools.ua ©   (2005-12-02 09:18) [98]

>>wal ©   (02.12.05 09:12) [97]

>Незнаю, достойно ореха или нет
IMHO, достойно.  %)


 
12DFBDD   (2005-12-02 09:28) [99]

wal ©   (02.12.05 09:12) [97]
это называется переработал


 
Владислав ©   (2005-12-02 09:29) [100]


> Lamer@fools.ua ©   (02.12.05 09:18) [98]
> IMHO, достойно.  %)


ИМХО, не достойно. В case нет else :o)


 
Владислав ©   (2005-12-02 09:47) [101]


> Не факт. Такой код нормально читается. Если это сделано
> не в каком-то критичном по скорости месте (а обычно всякие
> такие строковые штуки нужны при выводе результата, что никак
> не критично в смысле скорости) - тогда нормальный код. У
> меня такие примерно функции работают в нескольких программах.
>  Может это и не эталон.


Ну вот видите, Вы пытаетесь предположить, как этот код будет работать. В следующем же абзаце Вы говорите о том, что автор мог чделать что-то на будущее. Так как же с этим будущим? Какое оно будет для этой процедуры? Возметесь делать прогнозы? ;)
А в конкретной ситуации такая процедура вызывалась большое количество раз в течении работы программы. Хотя и не в критичном по скорости участке кода.
Не возмусь судить, как влияет фрагментация памяти на работоспособность программы. А такая процедура именно этим и занимается.


> Метод Terminate мог быть вызван в другом потоке.


Это бы никак не повлияло бы на результат. Смотрите: "В поточной функции свойство Terminated не проверялось." Хотя вру. Я же сам и добавил вызов Terminate в основном потоке, когда нашел этот код. Тут же схлопотал AV, как и предполагал.
В контексте результата работы приведенного кода вот это: "автор кода думал о будущем" звучит, как верх оптимизма, я бы сказал.
Типа того: "Когда-нибудь моя программа заработает! Я в это верю!" :)

Сказанное, ясен пень, не в Ваш адрес. Я понимаю, что без контекста иногда трудно о чем то судить.


 
Sha ©   (2005-12-02 09:54) [102]

> Lamer@fools.ua ©   (02.12.05 09:07) [96]
> Или даже так:

function ExpandWithSpaces(const S: String; NewLength: Integer): String;
var
 OldLength: Integer;
begin
 OldLength:=Length(S);
 if NewLength<=OldLength then Result:=S
 else begin
   SetLength(Result,NewLength);
   Move(pointer(S)^,pointer(Result)^,OLdLength);
   FillChar(pchar(pointer(Result))[OldLength], NewLength-OldLength, #32);
 end;
end;


 
Lamer@fools.ua ©   (2005-12-02 10:22) [103]

>>Sha ©   (02.12.05 09:54) [102]

А так вообще "кульно и рульно" ©. Не считая форматирования кода :o)


 
Piero   (2005-12-02 10:37) [104]

Игорь Шевченко ©, да



Страницы: 1 2 3 вся ветка

Текущий архив: 2005.12.25;
Скачать: CL | DM;

Наверх




Память: 0.81 MB
Время: 0.059 c
8-1122111225
lord Zeratul
2005-07-23 13:33
2005.12.25
Длина PlayList-а в WinAmp 2.x в секундах


6-1126951071
redlord
2005-09-17 13:57
2005.12.25
задержки при коннекте


14-1133536787
Хинт
2005-12-02 18:19
2005.12.25
Screenshot в Dos е под WinXP


4-1130147239
RainKm
2005-10-24 13:47
2005.12.25
Как узнать пустая ли папка?


1-1133431959
Andron.Ru
2005-12-01 13:12
2005.12.25
Как выдернуть текст из адресной строки Explorera