Re[42]: ЧОЧО?
От: -_*  
Дата: 27.10.10 11:18
Оценка:
Здравствуйте, hattab, Вы писали:

H>Повторить полный аналог можно и в дельфях, с той лишь разницей, что код она не сгенерирует В этом чтоли вся прелесть?


Конечно. Итератор для графа можно писать неделями, поверь. А если с помощью компилятора то где то за минуты можно управиться.

H>-_*>
H>-_*> foreach(Item item in GetNextItem())
H>-_*> {
H>-_*> // бесконечный цикл создания объектов
H>-_*> // со "структурами" на это памяти не хватит
H>-_*> }
H>-_*>

H>-_*> Можно идти и дальше — обход любой сложной структуры вроде дерева, кольца, графа или генерация сложной последовательности делается довольно просто.

H>Хм, что же в таком случае заставляет разработчиков самостоятельно писать перечислители?


Очевидно ты привел пример кода версии 1.0 или 1.1. В 2.0 и выше код который ты показал ужмется минимум в 10 раз.

H>-_*> А вот в Дельфи с итераторами придется попотеть.


H>Реализация одного метода это попотеть?


Итератор это не метод.
Материал из Википедии — свободной энциклопедии, -_*
Re[46]: ЧОЧО?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.10.10 11:29
Оценка:
Здравствуйте, hattab, Вы писали:

H>Здравствуйте, gandjustas, Вы писали:


g>> g>> H>Повторить полный аналог можно и в дельфях, с той лишь разницей, что код она не сгенерирует В этом чтоли вся прелесть?


g>> g>> Ну покажи полный аналог для такого
Автор: gandjustas
Дата: 26.10.10
например.


g>> H>Т.е. ты мне на полном серьезе предлагаешь тут реализовать собственный Rx? Шутник, однако.


g>> Нет, конкретный пример повтори с итератором, можно без асинхронности.


H>Если я правильно понял, это чтение из потока.


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

Так вот итераторы позволяют этот цикл сделать асинхронным, так как сам yield прерывает выполнение функции, а некоторый движок обеспечивает асинхронный запуск асинхронных операций.

Я вот спрашиваю как можно вот такое прерывание на delphi сделать.
Re[47]: ЧОЧО?
От: BlackEric http://black-eric.lj.ru
Дата: 27.10.10 12:23
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, hattab, Вы писали:


H>>Здравствуйте, gandjustas, Вы писали:


g>>> g>> H>Повторить полный аналог можно и в дельфях, с той лишь разницей, что код она не сгенерирует В этом чтоли вся прелесть?


g>>> g>> Ну покажи полный аналог для такого
Автор: gandjustas
Дата: 26.10.10
например.


g>>> H>Т.е. ты мне на полном серьезе предлагаешь тут реализовать собственный Rx? Шутник, однако.


g>>> Нет, конкретный пример повтори с итератором, можно без асинхронности.


H>>Если я правильно понял, это чтение из потока.


G>Неправильно понял.

G>При читении из потока указывается буфер, сколько байт прочитать и с какой позиции писать в буфер. Так как операция чтения может прочитать меньше, чем было указано, то для полного чтения буфера реализуется цикл, на каждой итерации которого двигается позиция для записи и уменьшается число байт, которое надо прочитать.

G>Так вот итераторы позволяют этот цикл сделать асинхронным, так как сам yield прерывает выполнение функции, а некоторый движок обеспечивает асинхронный запуск асинхронных операций.


G>Я вот спрашиваю как можно вот такое прерывание на delphi сделать.


Через callback?
https://github.com/BlackEric001
Re[47]: ЧОЧО?
От: hattab  
Дата: 27.10.10 12:24
Оценка:
Здравствуйте, gandjustas, Вы писали:

g> При читении из потока указывается буфер, сколько байт прочитать и с какой позиции писать в буфер. Так как операция чтения может прочитать меньше, чем было указано, то для полного чтения буфера реализуется цикл, на каждой итерации которого двигается позиция для записи и уменьшается число байт, которое надо прочитать.


g> Так вот итераторы позволяют этот цикл сделать асинхронным, так как сам yield прерывает выполнение функции, а некоторый движок обеспечивает асинхронный запуск асинхронных операций.


Ты же сам сказал, можно без асинхронщины

g> Я вот спрашиваю как можно вот такое прерывание на delphi сделать.


Тю. Да я бы вообще это без итератора сделал Для такой фигни еще итераторы задействовать...
 Offset := 0;
 Repeat

  Inc(Offset, FStream.Read(FBuffer[Offset], Length(FBuffer) - Offset));

 Until Offset = Length(FBuffer);

Сам понимаешь, что завернуть такой код в итератор труда тоже не составит.
avalon 1.0rc3 rev 363, zlib 1.2.3
Re[43]: ЧОЧО?
От: hattab  
Дата: 27.10.10 12:24
Оценка:
Здравствуйте, -_*, Вы писали:

-_*> H>Повторить полный аналог можно и в дельфях, с той лишь разницей, что код она не сгенерирует В этом чтоли вся прелесть?

-_*> Конечно. Итератор для графа можно писать неделями, поверь. А если с помощью компилятора то где то за минуты можно управиться.

Да, у меня есть такой (обход RTTI дерева). Писал не неделю, но часа два точно убил.

-_*> Итератор это не метод.

Ок. Это два метода. Причем основная работа делается только в одном из них. По сути получаем конечный автомат. Бывает простой, бывает сложный. Но не невозможный.
avalon 1.0rc3 rev 363, zlib 1.2.3
Re[48]: ЧОЧО?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.10.10 12:27
Оценка:
Здравствуйте, hattab, Вы писали:

H>Здравствуйте, gandjustas, Вы писали:


g>> При читении из потока указывается буфер, сколько байт прочитать и с какой позиции писать в буфер. Так как операция чтения может прочитать меньше, чем было указано, то для полного чтения буфера реализуется цикл, на каждой итерации которого двигается позиция для записи и уменьшается число байт, которое надо прочитать.


g>> Так вот итераторы позволяют этот цикл сделать асинхронным, так как сам yield прерывает выполнение функции, а некоторый движок обеспечивает асинхронный запуск асинхронных операций.


H>Ты же сам сказал, можно без асинхронщины

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

g>> Я вот спрашиваю как можно вот такое прерывание на delphi сделать.


H>Тю. Да я бы вообще это без итератора сделал Для такой фигни еще итераторы задействовать...

H>
H> Offset := 0;
H> Repeat

H>  Inc(Offset, FStream.Read(FBuffer[Offset], Length(FBuffer) - Offset));

H> Until Offset = Length(FBuffer);
H>

H>Сам понимаешь, что завернуть такой код в итератор труда тоже не составит.
Не понимаю. Как после Inc прервать выполнение метода? (например для шедулинга операций чтения)?
Re[44]: ЧОЧО?
От: -_*  
Дата: 27.10.10 12:48
Оценка:
Здравствуйте, hattab, Вы писали:

H>-_*> Итератор это не метод.


H>Ок. Это два метода. Причем основная работа делается только в одном из них. По сути получаем конечный автомат. Бывает простой, бывает сложный. Но не невозможный.


Да, получается именно автомат. Сначала нужно написать обход, а потом остаётся самое муторно — преобразовать код в автомат. Задача не сложная но ошибки здесь стоят очень дорого.
Материал из Википедии — свободной энциклопедии, -_*
Re[49]: ЧОЧО?
От: hattab  
Дата: 27.10.10 14:08
Оценка:
Здравствуйте, gandjustas, Вы писали:

g> H>Ты же сам сказал, можно без асинхронщины


g> ну правильно, нужно прерывание выполнение кода с сохранением контекста.


g> g>> Я вот спрашиваю как можно вот такое прерывание на delphi сделать.


Дроблением

g> H>Тю. Да я бы вообще это без итератора сделал Для такой фигни еще итераторы задействовать...

g> H>
g> H> Offset := 0;
g> H> Repeat

g> H>  Inc(Offset, FStream.Read(FBuffer[Offset], Length(FBuffer) - Offset));

g> H> Until Offset = Length(FBuffer);
g> H>

g> H>Сам понимаешь, что завернуть такой код в итератор труда тоже не составит.

g> Не понимаю. Как после Inc прервать выполнение метода? (например для шедулинга операций чтения)?


Ну, тут итератор не нужен вообще
TReader = Record

 Offset : Integer;
 Buffer : TBytes;

 Constructor Create(ABufferSize : Integer);
 Function GetBuffer(AStream : TStream) : Boolean;

End;

Constructor TReader.Create(ABufferSize : Integer);
Begin

 SetLength(Buffer, ABufferSize);

End;

Function TReader.GetBuffer(AStream : TStream) : Boolean;
Begin

 Inc(Offset, AStream.Read(Buffer[Offset], Length(Buffer) - Offset));
 Result := Offset = Length(Buffer);

End;

...

With TReader.Create(1024) Do
 While Not GetBuffer(Stream) Do
  Begin
   //shedule
  End;

А можно инициализировать стримом при создании ридера. В общем, есть варианты
avalon 1.0rc3 rev 363, zlib 1.2.3
Re[32]: ЧОЧО?
От: -_*  
Дата: 27.10.10 15:57
Оценка: :)
Здравствуйте, enji, Вы писали:

E>ну и что? После того, как я оформлю свой подход в либу, для пользователя он будет выглядеть не сильно страшнее твоего кода


На это уйдет время, не так ли ? На все случаи либ не напишешь.

E>-_*>Серия эвентов преобразуется в последовательность координат. Это + еще кое что есть распознавание мышиных жестов. В нативном подходе, с очередями, совпадениями, надо было писать килобайты ифов, свичей, обработчиков и трястись над различными флагами.


E>Распознавание мышиных жестов в дельфях из коробки. Килобайтов ифов там нет...


А как они жесты распознают ?

E>-_*>Расширение вроде RX написать на коленке ?


E>Ты не поверишь, но RX тоже кто-то написал


Это стандартная либа с широкими возможностями и благодаря ей не надо писать либы на все случае жизни, как "жестов в дельфях из коробки". Известная вобщем то проблема еще древнего Борланда — написать либы на все случаи жизни вместо хорошего фреймворка, через полгода-года обнаружить что случаев много больше, переписать все это с нуля и опять заточить на все случаи жизни вместо хорошего фреймворка и снова обнаружить что случаев много больше и тд.
Единственно, чего в дельфях и всех ex-борландовских продуктах вызывает уважение, так это непрекращающиеся попытки сделать мир лучше. Борланд под разными именами как птица феникс из пепла восстает — банкротится, выкупается, переформируется, выпускает продукт, снова банкротится.
Материал из Википедии — свободной энциклопедии, -_*
Re[32]: Почему Delphi всё еще жив?!
От: Head Ache  
Дата: 27.10.10 17:45
Оценка:
Здравствуйте, Eugeny__, Вы писали:

E__>Если в коде такое количество связей, и объекты друг на друга ссылаются, то проблема со скоростью GC уходит даже не на второй план, а сильно дальше, потому как самая главная проблема в днк писавшего такой код.


хотелось бы надеяться, что проблема хотя бы не в днк фреймворка
Этот аккаунт покинут.
Re[30]: Почему Delphi всё еще жив?!
От: Head Ache  
Дата: 27.10.10 17:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Ну и сколько ребер будет в графе? Очевидно что не N^2 потому что все со всеми живые объекты связаны не будут, то есть примерно количество ребер в графе будет линейно зависеть от количества вершин. В итоге тот же O(N) получим


Ощущение, что ты не совсем понимаешь что значит "доказать".
1% объектов имеют число связей, пропорциональных N, 99% имеют 0 связей => общая оценка O(N^2)
Этот аккаунт покинут.
Re[33]: Почему Delphi всё еще жив?!
От: Eugeny__ Украина  
Дата: 27.10.10 19:40
Оценка:
Здравствуйте, Head Ache, Вы писали:


E__>>Если в коде такое количество связей, и объекты друг на друга ссылаются, то проблема со скоростью GC уходит даже не на второй план, а сильно дальше, потому как самая главная проблема в днк писавшего такой код.


HA>хотелось бы надеяться, что проблема хотя бы не в днк фреймворка



Есть примеры фреймворка, который создает ссылки "все ко всем" между объектами?
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Re[33]: ЧОЧО?
От: enji  
Дата: 27.10.10 19:45
Оценка:
Здравствуйте, -_*, Вы писали:

E>>ну и что? После того, как я оформлю свой подход в либу, для пользователя он будет выглядеть не сильно страшнее твоего кода


-_*>На это уйдет время, не так ли ? На все случаи либ не напишешь.

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

E>>Распознавание мышиных жестов в дельфях из коробки. Килобайтов ифов там нет...


-_*>А как они жесты распознают ?

А я откуда знаю? Я про это читал, но дельфи давно уже не использую. А что, наличие Rx — обязательное условие для распознавания жестов? Насколько я все это понимаю, достаточно записать посл движений и сравнить с образцом. Алгоритм сравнения — это уже интересный вопрос. В институте на нейронных сетях делал какое-то распознавание...

-_*>Это стандартная либа с широкими возможностями и благодаря ей не надо писать либы на все случае жизни, как "жестов в дельфях из коробки". Известная вобщем то проблема еще древнего Борланда — написать либы на все случаи жизни вместо хорошего фреймворка, через полгода-года обнаружить что случаев много больше, переписать все это с нуля и опять заточить на все случаи жизни вместо хорошего фреймворка и снова обнаружить что случаев много больше и тд.

Часто оказывается что случаев даже больше, чем покрывает фреймворк И приходится его допиливать или писать что-то сбоку.
Re[50]: ЧОЧО?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.10.10 20:11
Оценка:
Здравствуйте, hattab, Вы писали:

H>Здравствуйте, gandjustas, Вы писали:


g>> H>Ты же сам сказал, можно без асинхронщины


g>> ну правильно, нужно прерывание выполнение кода с сохранением контекста.


g>> g>> Я вот спрашиваю как можно вот такое прерывание на delphi сделать.


H>Дроблением


g>> H>Тю. Да я бы вообще это без итератора сделал Для такой фигни еще итераторы задействовать...

g>> H>
g>> H> Offset := 0;
g>> H> Repeat

g>> H>  Inc(Offset, FStream.Read(FBuffer[Offset], Length(FBuffer) - Offset));

g>> H> Until Offset = Length(FBuffer);
g>> H>

g>> H>Сам понимаешь, что завернуть такой код в итератор труда тоже не составит.

g>> Не понимаю. Как после Inc прервать выполнение метода? (например для шедулинга операций чтения)?


H>Ну, тут итератор не нужен вообще

H>
H>TReader = Record

H> Offset : Integer;
H> Buffer : TBytes;

H> Constructor Create(ABufferSize : Integer);
H> Function GetBuffer(AStream : TStream) : Boolean;

H>End;

H>Constructor TReader.Create(ABufferSize : Integer);
H>Begin

H> SetLength(Buffer, ABufferSize);

H>End;

H>Function TReader.GetBuffer(AStream : TStream) : Boolean;
H>Begin

H> Inc(Offset, AStream.Read(Buffer[Offset], Length(Buffer) - Offset));
H> Result := Offset = Length(Buffer);

H>End;

H>...

H>With TReader.Create(1024) Do
H> While Not GetBuffer(Stream) Do
H>  Begin
H>   //shedule
H>  End;
H>

H>А можно инициализировать стримом при создании ридера. В общем, есть варианты

Ну вот ты почти сделал ту работу, которую компилятор C# делает автоматически.
Re[49]: ЧОЧО?
От: std.denis Россия  
Дата: 27.10.10 20:55
Оценка:
G>Не понимаю. Как после Inc прервать выполнение метода? (например для шедулинга операций чтения)?
Попробую тряхнуть стариной Хотя стотыщлет не пробовал Delphi, может TClientSocket не самый лучший вариант, да и современные модификации языка скорее позволят сделать много проще.
  TExactReader
type
  TExactReaderDone = procedure (Sender: TExactReader) of object;
  TExactReader = class
    Buffer: TBytes;
    BufferPos, BufferSize: Cardinal;

    property OnDone: TExactReaderDone;
    procedure DataReceived(Sender: TObject; Socket: TCustomWinSocket)
    var
      DataLen: Integer;
    begin
      DataLen := Socket.ReceiveLength;
      if BufferSize < DataLen then DataLen := BufferSize;

      Socket.ReceiveBuf(@Buffer[BufferPos], DataLen);
      Inc(BufferPos, DataLen);
      Dec(BufferSize, DataLen);
      
      if BufferSize = 0 then      
        OnDone(Self);
    end;

    constructor Create(Sock: TClientSocket; Size: Cardinal; Handler: TExactReaderDone)
    begin
      BufferSize := Size;
      BufferPos := 0;
      SetLength(Buffer, BufferSize);

      OnDone := Handler;
      Sock.OnRead := DataReceived;
    end;
    destructor Destroy
    begin
      Sock.OnRead := nil;
    end;
  end;
Хотя вроде изначально речь шла о работе со сложными данными, с переменными полями, когда размер получается по ходу чтения.
Тов. gandjustas, а как выглядит код её вызывающий ReadExact?
  Вот еще один вариант, может тоже не совсем уж плох?
type
  TDataStreamReceived = procedure (Sender: TDataStreamer) of object;
  TDataStreamer = class
    Buffer: TBytes;
    BufferPos, BufferSize: Cardinal;
  
    property OnReceived: TDataStreamReceived;
    procedure DataReceived(Sender: TObject; Socket: TCustomWinSocket)
    var
      DataLen: Integer;
    begin
      DataLen := Socket.ReceiveLength;
      if ((BufferPos+DataLen) >= BufferSize) or not Assigned(Buffer) then
      begin
        while (BufferPos+DataLen) >= BufferSize do BufferSize := BufferSize*2;
        SetLength(Buffer, BufferSize);
      end;
      Socket.ReceiveBuf(@Buffer[BufferPos], DataLen);
      Inc(BufferPos, DataLen);
      
      OnReceived(Self);
    end;
    
    procedure RemoveHandled(Size: Cardinal)
    begin
      MoveMemory(@Buffer[0], @Buffer[Size], BufferPos-Size);
      Dec(BufferPos, Size);
    end;
    
    constructor Create(Sock: TClientSocket)
    begin
      Buffer := nil;
      BufferPos := 0;
      BufferSize := 4*1024;
      
      Sock.OnRead := DataReceived;
    end;
    
    destructor Destroy
    begin
      Sock.OnRead := nil;
    end;
    
    function GetByte(var AtPos: Cardinal; var Data: Byte): Boolean;
    function GetWord(var AtPos: Cardinal; var Data: Word): Boolean;
    function GetDWord(var AtPos: Cardinal; var Data: DWord): Boolean;
    function GetString(var AtPos: Cardinal; var S: String): Boolean;
  end;
  
  TCommandProcessor = class
    Sock: TClientSocket;
    Streamer: TDataStreamer;

    procedure OnData(Stream: TDataStreamer)
    var
      Cmd: Word;
      Text: string;
      DataType, ValueIndex: DWord;
      I: Cardinal;
    begin
      I := 0;

      if not S.GetWord(I, Cmd) then Exit;
      case Cmd of
        $0001: begin
          if not GetString(I, Text) then Exit;
          MessageBox(0, text, 'A message', MB_OK);
        end;
        $1001: begin
          if not S.GetDWord(I, DataType) then Exit;
          if not S.GetDWord(I, ValueIndex) then Exit;
          ProcessInformationRequest(DataType, ValueIndex);
        end;
      end;

      S.RemoveHandled(I);
    end;

    constructor Create(Sock: TClientSocket)
    begin
      Streamer := TDataStreamer.Create(Sock);
      Streamer.OnReceived := OnData;
    end;
  end;
Re[31]: Почему Delphi всё еще жив?!
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.10.10 21:09
Оценка:
Здравствуйте, Head Ache, Вы писали:

HA>Здравствуйте, gandjustas, Вы писали:


G>>Ну и сколько ребер будет в графе? Очевидно что не N^2 потому что все со всеми живые объекты связаны не будут, то есть примерно количество ребер в графе будет линейно зависеть от количества вершин. В итоге тот же O(N) получим


HA>Ощущение, что ты не совсем понимаешь что значит "доказать".

Я вообще-то не очень понимаю что вообще хочется доказать?

HA>1% объектов имеют число связей, пропорциональных N, 99% имеют 0 связей => общая оценка O(N^2)

N что такое?
Это видимо тот самый случай когда O(N^2) оказывается меньше O(N).
Собственно сама асимптотика GC вообще-то не интересует. Интересует реальная скорость работы, которая достигается оптимизациями и хаками.
Re[34]: Почему Delphi всё еще жив?!
От: Head Ache  
Дата: 27.10.10 22:46
Оценка:
Здравствуйте, Eugeny__, Вы писали:

E__>Есть примеры фреймворка, который создает ссылки "все ко всем" между объектами?


Не появляются ли неявно, где-то внутри связи типа не "все ко всем", а "один ко многим".
Этот аккаунт покинут.
Re[32]: Почему Delphi всё еще жив?!
От: Head Ache  
Дата: 27.10.10 23:08
Оценка: :)
Здравствуйте, Eugeny__, Вы писали:

E__>Если в коде такое количество связей, и объекты друг на друга ссылаются, то проблема со скоростью GC уходит даже не на второй план, а сильно дальше, потому как самая главная проблема в днк писавшего такой код.


Ну что вас заставляет писать ВОТ ЭТО, да еще и хвастаться:

(http://www.rsdn.ru/forum/flame.comp/4015178.aspx
Автор: Head Ache
Дата: 27.10.10
)

public Item GetNextItem()
{
return new Item();
}

Как ты думаешь, что это такое ? В дотнет это почти последовательность — если вызвать n-раз. Что бы стало по настоящему последовательностью, нужно заставить компилятор генерировать чуток кода:
public IEnumarable<Item> GetNextItem()
{
while(true)
{
yeild return new Item();
}
}
....
Все просто и никаких "структур" не надо.

foreach(Item item in GetNextItem())
{
// бесконечный цикл создания объектов
// со "структурами" на это памяти не хватит
}
Этот аккаунт покинут.
Re[33]: Почему Delphi всё еще жив?!
От: Head Ache  
Дата: 27.10.10 23:17
Оценка:
HA>foreach(Item item in GetNextItem())
HA>{
HA>// бесконечный цикл создания объектов
HA>// со "структурами" на это памяти не хватит
HA>}

зы: а потом другой умник не глядя втыкает подобную хрень в какой-нибудь многопоточный обработчик...
Этот аккаунт покинут.
Re[34]: ЧОЧО?
От: -_*  
Дата: 28.10.10 00:26
Оценка:
Здравствуйте, enji, Вы писали:

E>Ну так на все случаи и не надо Надо только на конкретные случаи. Причем где-то надо именно либу, а где то хватит обычного "одноразового" кода, который решает задачу. Запись событий мышки — типичный пример такого кода, который очень прост и элементарно пишется каждый раз с учетом потребностей.


Такой код слишком прост что бы писать его каждый раз.

E>>>Распознавание мышиных жестов в дельфях из коробки. Килобайтов ифов там нет...

E>-_*>А как они жесты распознают ?

E>А я откуда знаю? Я про это читал, но дельфи давно уже не использую. А что, наличие Rx — обязательное условие для распознавания жестов?


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

>Насколько я все это понимаю, достаточно записать посл движений и сравнить с образцом. Алгоритм сравнения — это уже интересный вопрос. В институте на нейронных сетях делал какое-то распознавание...


RX позволяет свести это исключительно к алгоритму распознавания.

E>-_*>Это стандартная либа с широкими возможностями и благодаря ей не надо писать либы на все случае жизни, как "жестов в дельфях из коробки". Известная вобщем то проблема еще древнего Борланда — написать либы на все случаи жизни вместо хорошего фреймворка, через полгода-года обнаружить что случаев много больше, переписать все это с нуля и опять заточить на все случаи жизни вместо хорошего фреймворка и снова обнаружить что случаев много больше и тд.


E>Часто оказывается что случаев даже больше, чем покрывает фреймворк И приходится его допиливать или писать что-то сбоку.


Хороший фреймворк не затачивается на все случаи, он пишется с рассчетом на то, в том числе, что его можно будет допилить или написать чтото сбоку. А у борланда испокон веков идея фикс — покрыть все возможные случаи.
Материал из Википедии — свободной энциклопедии, -_*
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.