Форум: "Прочее";
Текущий архив: 2006.08.13;
Скачать: [xml.tar.bz2];
Внизвсё -- досисадминился Найти похожие ветки
← →
Ketmar © (2006-07-18 23:49) [0]забыл, что в until кроме false ьщжно писать условие выхода. автоматически написал нечто вроде
repeat
...
if condition then break;
until false;
пайду, убьюсь ап стену...
← →
Ketmar © (2006-07-18 23:49) [1]тьфу. ещё и печатать напрочь разучился...
← →
Rouse_ © (2006-07-18 23:53) [2]можно и не писать :)
← →
grisme © (2006-07-18 23:55) [3]ТЕРЯЕМ!..:) СРОЧНО ПРОВОДИТЬ ВОССТАНОВИТЕЛЬНО-ПРОФИЛАКТИЧЕСКИЕ РАБОТЫ..
← →
Ketmar © (2006-07-19 00:02) [4]>Rouse_ © (18.07.06 23:53) [2]
можно. просто, увидев у кого-то такой код, я бы не преминул кинуть увесистый булыжник. %-))
>grisme © (18.07.06 23:55) [3]
да. увольняться надо... но тогда я без денег останусь -- работать дома мне жутко лениво. а так хоть какой-то стимул. %-)
зыж стену стало жалко. "эльфы юные, головы чугунные"...
← →
grisme © (2006-07-19 00:06) [5]> "эльфы юные, головы чугунные"...
Ж:D
← →
Marser © (2006-07-19 00:39) [6]Пить надо меньше (Ц)
← →
Джо © (2006-07-19 00:41) [7]> пайду, убьюсь ап стену...
Пааагоди, пааавремени —
Утро мудренее...
(c)
← →
grisme © (2006-07-19 00:46) [8]Marser
Наш "юный" товарищьч ныне сисадминь :), а трезвыми их врядли вообще можно увидеть(хотя, думаю, Кейт и до этого не щеголял прозрачным)...
← →
Ketmar © (2006-07-19 01:20) [9]>Marser © (19.07.06 00:39) [6]
пробовал. ещё противнее.
>Джо © (19.07.06 00:41) [7]
тогда посплю.
>grisme © (19.07.06 00:46) [8]
можно, можно... я на работе трезвый. или с бодуном, но это не важно.
← →
Piter © (2006-07-19 02:14) [10]Ketmar © (18.07.06 23:49)
repeat
...
if condition then break;
until false
нда... Как такое можно забыть?...
← →
Ketmar © (2006-07-19 09:50) [11]ну, пусть не совсем забыл. просто там в середине цикла пара условий на выход. вот и в конце написал "на автомате" такое же.
в принципе, я часто использую "repeat .. until false" с брыками в серёдке.
а намедни обнаружил в программе ещё более чудную конструкцию: repeat ... until true. %-) удалять не стал.
← →
tsa (2006-07-19 09:52) [12]Это черный цвет влияет ;-)
← →
Шпиён (2006-07-19 10:00) [13]
> Ketmar © (19.07.06 09:50) [11]
Бывает -) За собой тоже замечаю - последние два-три года программировать удается только в свободное время.... так такие ляпы начал сажать иногда.... самому жутко -(
"Автопилот" тренировать надо, и все будет -)
← →
Rouse_ © (2006-07-19 10:17) [14]
> можно. просто, увидев у кого-то такой код, я бы не преминул
> кинуть увесистый булыжник.
А чем плох такой код?
← →
Ketmar © (2006-07-19 10:39) [15]>Rouse_ © (19.07.06 10:17) [14]
да, в принципе, ничем. просто сразу навевает мысли о незнании матчасти и тупом copy/paste. %-)
← →
Rouse_ © (2006-07-19 10:42) [16]Не, всетаки я не понял :) При чем тут незнание матчасти? Ну нужен мне бесконечный цикл и что? Я матчасть не знаю? :)
А если мне нужен бесконечный цикл внутри которого вызывается некоторый эвент, на обработчике которого пользователь сам решает - крутить дальше или выходить, тогда как? :)
← →
umbra © (2006-07-19 10:45) [17]
> repeat
> ...
> if condition then break;
> until false;
это же, можно сказать, заготовка для сервера :)
← →
tsa (2006-07-19 10:46) [18]На завод! к печи - что нибудь закидывать. а то код не нравится! :)
← →
Rouse_ © (2006-07-19 10:46) [19]к примеру:
try
repeat
if Assigned(SomeEvent) then
SomeEvent(Self);
until False;
except
on E: EAbort do
WriteLog("Done");
on E: Exception do
raise;
end;
← →
Rouse_ © (2006-07-19 10:48) [20]
> это же, можно сказать, заготовка для сервера :)
Собственно это рабочий цикл по крайней мере сервиса :)
← →
Piter © (2006-07-19 10:54) [21]Rouse_ © (19.07.06 10:46) [19]
к примеру:
try
repeat
if Assigned(SomeEvent) then
SomeEvent(Self);
until False;
неправильная логика программы. Бесконечные циклы это вообще плохо.
Это значит у тебя будет генерироваться событие бесконечно подряд до тех пор, пока кто-то там во внешней процедуре не обнулит это указатель на обработчик. Это не грамотно.
Имхо :)
← →
Плохиш © (2006-07-19 11:15) [22]
> Rouse_ © (19.07.06 10:46) [19]
Не надо делать офтопиков, в оригинале было
> if condition then break;
> until false;
и ни каких команд между if и until.
← →
Rouse_ © (2006-07-19 11:15) [23]
> неправильная логика программы. Бесконечные циклы это вообще
> плохо.
>
> Это значит у тебя будет генерироваться событие бесконечно
> подряд до тех пор, пока кто-то там во внешней процедуре
> не обнулит это указатель на обработчик. Это не грамотно.
>
Да ну? Вообщето в примере показан вечный цикл с отловом Abort-а :)
А по поводу бесконечных циклов - это кто сказал что плохо? Поговорку ИШ про овощь помнишь? ;)
← →
Rouse_ © (2006-07-19 11:16) [24]
> Плохиш ©
Тоже скажешь что это плохо? ;)
← →
Плохиш © (2006-07-19 11:21) [25]
> Rouse_ © (19.07.06 11:16) [24]
>
> > Плохиш ©
>
> Тоже скажешь что это плохо?
Нафига ставить кучу goto туда где можно обойтись if-ом?
← →
Rouse_ © (2006-07-19 11:33) [26]Нафига - это знаетели както бездоказательно звучит. Где теоретическая база которая побводит под запрет использования таких конструкций? :)
← →
Piter © (2006-07-19 11:43) [27]Rouse_ © (19.07.06 11:15) [23]
Да ну? Вообщето в примере показан вечный цикл с отловом Abort-а :)
а какой смысл вот так подряд вызывать события?
А по поводу бесконечных циклов - это кто сказал что плохо?
я сказал. И ты это знаешь. Бесконечный цикл - бесконечно долго загружает процессор, программа отрабатывает бесконечно во времени. Зачем это?
Приведи КОНКРЕТНЫЙ практический пример использования:until false;
← →
Rouse_ © (2006-07-19 12:00) [28]
> Приведи КОНКРЕТНЫЙ практический пример использования:
Легко.
Утилита восстановления поврежденного файла формата POIFS
Ищем битый блок при обращении к которому возникнет Exception.if StgIsStorageFile(StringToOleStr(AFileName)) <> S_OK then
try
PreviosValidOffset := 0;
repeat
PreviosValidOffset := TPoifsPropsBlock(GetBlock(PreviosValidOffset));
... рассчет смещений и попытка обращению к блоку
... при успешном достижении конца цепочки (рассчитывается), произойдет вызов Abort
until False;
except
on E: EAbort do Result := S_OK;
on E: EBatException do
Result := FixBatEntry(PreviosValidOffset);
on E: EXBatException do
Result := FixExtendedBatEntry(PreviosValidOffset);
on E: Exception do raise;
end;
← →
Piter © (2006-07-19 18:10) [29]Rouse_ © (19.07.06 12:00) [28]
налицо неграмотное использование исключений. Это где ты видел такое вообще:
Rouse_ © (19.07.06 12:00) [28]
... при успешном достижении конца цепочки (рассчитывается), произойдет вызов Abort
Функция GetBlock при своем так сказать успешном завершении вызывает Abort? Чтобы во внешней процедуре этот Abort ловить? :)))
Тебе не кажется, что это как-то нелогично?
Функция при своем успешном заверщении должна не исключение генерировать, а возвращать соответствующее значение, ну например 0.
Тагды:
const
cBLOCK_COMPLETE = 0;
...
if StgIsStorageFile(StringToOleStr(AFileName)) <> S_OK then
try
PreviosValidOffset := 0;
repeat
PreviosValidOffset := TPoifsPropsBlock(GetBlock(PreviosValidOffset));
until PreviosValidOffset = cBLOCK_COMPLETE;
Result := S_OK;
except
on E: EBatException do
Result := FixBatEntry(PreviosValidOffset);
on E: EXBatException do
Result := FixExtendedBatEntry(PreviosValidOffset);
on E: Exception do raise;
end;
← →
Rouse_ © (2006-07-19 18:22) [30]
> Функция GetBlock при своем так сказать успешном завершении
> вызывает Abort? Чтобы во внешней процедуре этот Abort ловить?
> :)))
>
> Тебе не кажется, что это как-то нелогично?
А тебе не кажется что ты по крайней мере немного не в теме и вот это: PreviosValidOffset = cBLOCK_COMPLETE; выгледит немного бредово :)
это раз.
Второе: аборт в этой функции никогда не вызовиться и оставлен только на всякий случай ибо определить конец не получиться. StgIsStorageFile вернул не S_OK и как минимум одно исключение типа EBatException появиться в процессе трассировки.
Третье. Дерево SBAT XBAT блоков может указывать на уже пройденные блоки рекурсивно, таким макаром ты никогда на конец цепочки не выйдешь.
Четвертое, каждое обращение к блоку обрабатывает несколько классов (юниты по пару тысяч строк) и каждый из них может вызвать исключение, которое транслируется в уже известный адрес и тип.
Ну и в пятых cBLOCK_COMPLETE = т.е. верный признак окончания цепочки прописан в конце каждой ветви до которой нужно еще дойти - напрямую не считаешь (если не ушли в рекурсию) и для каждой имеет разное значение :)
← →
Rouse_ © (2006-07-19 18:31) [31]Это я еще не показываю заморочки которые возникают при убитии самого начала блоков, обычно по 16 байт грохается под FAT32. Вот там прямой брутфорс этих 16 байт и попытка чтения после каждого изменения. Как только получилось что-то похожее на выход в таблицу - сохраняем в отдельный файл и брутфорсим дальше, ибо еще не факт что верно получилось.
← →
Piter © (2006-07-19 19:33) [32]Rouse_ © (19.07.06 18:22) [30]
А тебе не кажется что ты по крайней мере немного не в теме и вот это: PreviosValidOffset = cBLOCK_COMPLETE; выгледит немного бредово :)
это раз.
я немного не в теме ТВОЕЙ программы? Розыч, да я вообще не в теме ТВОЕЙ программы. Основываюсь только на тех данных, которые ты дал.
Почему выглядит бредово? Потому что константе дали название cBLOCK_[b]COMPLETE[/b]? Ну назови ее cBLOCK_ABORT, я не знаю - тебе виднее.
В любом случае - мне эта логика кажется неправильной, хотя трудно говорить, не знаю специфики твоей программы. Но ты сначала ОПРЕДЕЛЯЕШЬ, что исключение будет, а потом вызываешь бесконечный цикл, зная что там возникнет исключение. Причем, юнитов на пару тысяч строк.
Сложно тут говорить... Это специфика, пример уходит в основы работы программы, я так не разберусь в этом, чтобы свое мнение высказать.
Так что плиз, если можешь - приведи доступный пример, где нужно использовать:
until false;
Или пример, где используется:
while true do
что одно и тоже в целом.
← →
umbra © (2006-07-19 19:43) [33]
> приведи доступный пример, где нужно использовать:
>
> until false;
вопрос не ко мне, но вот вполне доступный (хотя и несколько абстрактный :)) пример постоянно работающего и не имеющего окон сервиса, обрабатывающего запросы клиентовrepeat
if ClientConnected then
ServeClient;
until false;
← →
Piter © (2006-07-19 19:47) [34]umbra © (19.07.06 19:43) [33]
repeat
if ClientConnected then
ServeClient;
until false
плохой пример. А сервис не рассматривает варианты, что его могут остановить?
Как минимум:
repeat
if ClientConnected then
ServeClient;
until Terminated;
← →
Vendict © (2006-07-19 20:44) [35]> приведи доступный пример, где нужно использовать:
>
> until false;
старый пример из паскаля, которым я всегда пользовался:repeat
c:=ReadKey;
//реакция на нажатия и выполнение необходимых операций
until False;
этот кусок всегда испльзуется в игровых "движках". не понимаю, чем он тебе не нравиться.
← →
Rouse_ © (2006-07-19 20:57) [36]
> Piter © (19.07.06 19:33) [32]
Мих, ты читаешь но не вчитываешся. Краткая компиляция того что я пытаюсь тебе обьяснить.
Есть бесконечный цикл, заведомо известно, что на одной из итераций цикла должно возникнуть исключение. Вопрос - нафига нам лишний IF когда выход через SEH нам полюбому обеспечен?
← →
Rouse_ © (2006-07-19 21:03) [37]
> А сервис не рассматривает варианты, что его могут остановить?
Сервис не должен рассматривать варианты остановки в своем потоке, все общение с SCM происходит не в потоке сервиса.
← →
Piter © (2006-07-19 21:11) [38]Розыч, я предъявляю претензии вот к этому:
заведомо известно, что на одной из итераций цикла должно возникнуть исключение
как такое может быть известно? Может, тогда и результаты итерации известны? Зачем тогда итерировать? :)
← →
Rouse_ © (2006-07-19 21:25) [39]
> как такое может быть известно? Может, тогда и результаты
> итерации известны?
Дело в том, что если StgIsStorageFile не вернула S_OK (см MSDN), но известно что это точно POIFS, то проход по дереву блоков неминуемо приведет к очибке чтения одного из банков данных, на которые указывает каждый блок. Какая это будет итерация - хрен его знает. Наши пользователи такие вещи умудряются присылать что волосы дыбом становяться... ммм... Обо что это я? А! Так вот, если вызов функции неуспешен - крутим цикл до упора и можно не сомневаться что будет АВ, ибо я делаю практически тоже что делает оригинальная StgIsStorageFile, просто она через SEH давит ошибку и возвращает S_FALSE, а я пытаюсь поправить блок. В данной ситуации нельзя определить когда будет конец цикла...
← →
Rouse_ © (2006-07-19 21:29) [40]Т.е. если ты понял я пытаюсь работать с файлом на уровне его физической структуры через read write (благо формат более менее известен), а не через АПИ. Это достаточно часная ситуация
← →
Piter © (2006-07-19 21:40) [41]Rouse_ © (19.07.06 21:25) [39]
вот, слушай, и я ведь об этом. Так если ты фактически повторяешь работу StgIsStorageFile - зачем ты ее вызываешь вообще?
То есть, сначала винда своими внутренними механизмами делает это, а потом ты повторно делаешь это уже на низком уровне. Но возникает вопрос - НАФИГА?
Если уж ты низкоуровнево разбираешь все равно - так и сделай до конца. Ведь как думаешь - у StgIsStorageFile есть критерии остановки работы, предотвращение от ухода в бесконечную рекурсию и прочее? Ну так и сделай такие же критерии в своем until, тогда и необходимость двойной работы отпадет :)
Я понимаю, почему реализовано так - потому что проще и быстрее так написать, тем более уж в системе есть такая функция. Но с другой то стороны - согласись, можно написать пограмотнее - и тогда необходимость в бесконечных циклах отпадет :)
← →
Rouse_ © (2006-07-19 21:44) [42]
> Так если ты фактически повторяешь работу StgIsStorageFile
> - зачем ты ее вызываешь вообще?
Дык, под FAT32 из-за нетранзакционной модели файлики бьются иногда. Пользователи которые заплатили по 800 зеленью начинают страшно нервничать - прихождиться писать. А вызываю я ее, чтобы удостовериться - битая цепочка или нет. Нормальное завершение цепочки - значения -1, -2, -3, -4 . Каждое из них что-то да означает. Финальное завершение цепочки -2. Если StgIsStorageFile не смогла самостоятельно выйти на конец цепи - начинаю работать я. Там просто помимо убития физической структуры иногда бьются банки данных. Т.е. цепочки сами целые, а данные частично покорежены. Мне нужн выяснить - какую часть алгоритма запускать для восстановления.
← →
Piter © (2006-07-19 21:47) [43]Rouse_ © (19.07.06 21:44) [42]
да, но опять же - Розыч, ведь функционал твоей программы перекрывает функционал StgIsStorageFile? Так зачем ты ее используешь?
← →
Rouse_ © (2006-07-19 21:55) [44]Так проще и быстрее определить :) У меня сильно расширенный функционал, который для простой проверки не нужен.
← →
DiamondShark © (2006-07-19 22:25) [45]
> а намедни обнаружил в программе ещё более чудную конструкцию:
> repeat ... until true. %-) удалять не стал.
И правильно сделал.
repeat
if not Tratata(...) then break;
if Halabala(...) <> HALABALA_NOERROR then break;
....
until true;
так иногда бывает. чтоб гоутуками пуристофф не пугать ;))
← →
Eraser © (2006-07-19 22:34) [46]> [42] Rouse_ © (19.07.06 21:44)
> Пользователи которые заплатили по 800 зеленью начинают страшно
> нервничать
неужели у этих пользователей нету ещё сотни $, чтобы установить нормальную ОС ? :)
← →
Piter © (2006-07-19 22:45) [47]Rouse_ © (19.07.06 21:55) [44]
Так проще и быстрее определить :)
ну насчет быстрее я не уверен. А проще - это да :)
У меня сильно расширенный функционал, который для простой проверки не нужен
вот именно. расширенный функционал, который перекрывает виндовый.
Сначала винда сканерит на ошибки, и если ошибки найдены - то в работу вступаешь ты :)
А почему бы самому не сканерить - сразу ловить ошибки и собственно удостоверяться - а есть ли они.
← →
Ketmar © (2006-07-19 22:50) [48]>DiamondShark © (19.07.06 22:25) [45]
и так делаю. но в данном случае это был обломок от действительно "псевдобесконечного" цикла. цикл планируется вернуть назад, потому и не удалил. %-)
а избегание goto в той софтине я делаю ещё интересней:try
...
if ZZZ then exit;
...
finally
...
end;
%-)
← →
jack128 © (2006-07-19 23:11) [49]Piter © (19.07.06 22:45) [47]
А почему бы самому не сканерить - сразу ловить ошибки и собственно удостоверяться - а есть ли они.
Потому что сначала нужно работать документированными средствами, а потом уже хакать формат файла. Да и потом, сначала писалась основная программа, которая работа через IStorage, и только потом, когда юзеры стали слать битые файлы, был написан Розычевский чинитель
← →
isasa © (2006-07-19 23:28) [50]Что-то ветка затихла
while true do begin
...
if condition then break;
end;
← →
Piter © (2006-07-20 02:48) [51]isasa © (19.07.06 23:28) [50]
while true do begin
...
if condition then break;
end;
а это что такое? Если я правильно понял - чистый repeat..until, нафига тут такой while?
← →
Rouse_ © (2006-07-20 09:55) [52]
> ну насчет быстрее я не уверен.
Быстрее - быстрее, у меня после чтения каждого участка идет анализ на рекурсию (если конечно еще AV не поймали). Там память в основном жрется. Ну и различные доп вычисления которые нехиленько грузят проц.
← →
Rouse_ © (2006-07-20 10:06) [53]
> неужели у этих пользователей нету ещё сотни $, чтобы установить
> нормальную ОС ? :)
Ты не поверишь. у некторых стоят уже двухядерные пни, НО!!! Windows 98
← →
umbra © (2006-07-20 10:12) [54]2 Piter © (19.07.06 19:47) [34]
> repeat
> if ClientConnected then
> ServeClient;
> until Terminated;
>
если этот сервис выполняет для клиента длительные по времени операции, то проверка на необходимость завершения на каждой итерации - плохая идея. К примеру, ФТП сервер выдает клиенту файл размером 2 гига по узкому (скажем, 10 кб/с), но очень устойчивому каналу. К тому же, этот сервер использует блокирующие сокеты. И вот, спустя 5 минут после начала закачки у сисадмина появляется необходимость остановить сервер. Если сделать так, как Вы предложили, то сколько придется ждать сисадмину, пока сервер остановится? :)
← →
Piter © (2006-07-20 13:34) [55]umbra © (20.07.06 10:12) [54]
. Если сделать так, как Вы предложили, то сколько придется ждать сисадмину, пока сервер остановится? :)
а если вместо Terminated вставить False, как тут предлагалось, то сколько надо будет ждать?
Не понимаю вопроса.
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2006.08.13;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.042 c