OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Среда, 18 Июнь, 2025 19:18

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 178 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 9  След.
Автор Сообщение
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 12:07 
Аватара пользователя

Зарегистрирован: Суббота, 19 Ноябрь, 2005 15:59
Сообщения: 803
Откуда: Зеленоград
Илья Ермаков писал(а):
А так в ББ для таких случаев и применяется спец. метод Close (если не вызвали его явно, тогда уже добивает финализатор). Files.File. SqlDB. И т.п.
Тогда следующий вопрос: будут ли освобождены системные ресурсы, если метод Close по каким-то причинам не был явно вызван (например, если где-то в дебрях кода "сработал" ASSERT или был вызван HALT)?
Я просто хочу для себя уяснить: существует ли проблема (и если существует, то насколько она серьезна)?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 12:09 
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Если метод Close не вызван явно, его вызовет финализатор при сборе мусора.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 12:16 
Аватара пользователя

Зарегистрирован: Суббота, 19 Ноябрь, 2005 15:59
Сообщения: 803
Откуда: Зеленоград
Geniepro писал(а):
Хорошо бы ещё добавить for each, ибо куда без него...
Думается, for each вполне может быть и методом контейнера. Это как раз непринципиальный вопрос.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 12:21 
Аватара пользователя

Зарегистрирован: Суббота, 19 Ноябрь, 2005 15:59
Сообщения: 803
Откуда: Зеленоград
Илья Ермаков писал(а):
Если метод Close не вызван явно, его вызовет финализатор при сборе мусора.
Это да.
Сомнений в том, что ресурсы будут освобождены, нет.
Вопрос только в своевременности их освобождения.
Теоретически, может имеет смысл насильно привязать вызов сборщика мусора к HALT/ASSERT (например, сразу после закрытия окошка трапа; или подменить вызов отладчика на вызов сборщика мусора для программ, передаваемых пользователю)?
Тогда ресурсы будут освобождены в более-менее предсказуемое время.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 13:12 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
AVC писал(а):
Илья Ермаков писал(а):
Если метод Close не вызван явно, его вызовет финализатор при сборе мусора.
Сомнений в том, что ресурсы будут освобождены, нет.
Вопрос только в своевременности их освобождения.
Я так понимаю, что речь о своевременности освобождении ресурсов имеет смысл вести только для случая нормальной работы программы. Ведь только нормально написанная программа вызывает всяческие Close своевременно. В случае же, если программа написана небрежно или, тем более, содержит серьёзные ошибки, провоцирующие HALT/ASSERT, говорить о своевременности освобождения ресурсов попросту неуместно. За посмертное освобождение ресурсов должна отвечать операционная система как контейнер-владелец конкретного умершего приложения. В качестве такого владельца может выступать и рантайм Блэкбокса, так что вызов сборки мусора по HALT/ASSERT представляется вполне уместным.

Мне кажется, что механизм исключений размывает, делает нечётким представление о том, что такое корректно работающая программа. Когда говорят, что данная процедура при корректных входных параметрах может либо вернуть значение в OUT-параметре, либо выбросить исключение EDivByZero, то мне представляется, что разработчики при проектировании не потрудились подумать головой и сделать осмысленный интерфейс. Ведь чем более низкоуровневое исключение я "поймал" наверху, тем меньше у меня информации о том, где и почему оно возникло, как мне избежать его в дальнейшем, и что мне в этой связи показать пользователю. Тем более, что все эти исключения могут добавляться, изменяться и удаляться без малейшего изменения программного интерфейса, и вообще в этой связи не являются частью контракта. : (


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 13:45 
Аватара пользователя

Зарегистрирован: Суббота, 19 Ноябрь, 2005 15:59
Сообщения: 803
Откуда: Зеленоград
Александр Ильин писал(а):
За посмертное освобождение ресурсов должна отвечать операционная система как контейнер-владелец конкретного умершего приложения. В качестве такого владельца может выступать и рантайм Блэкбокса, так что вызов сборки мусора по HALT/ASSERT представляется вполне уместным.
По крайней мере, это решение (пока) кажется самым простым.
Дождёмся критики. :)

Александр Ильин писал(а):
Мне кажется, что механизм исключений размывает, делает нечётким представление о том, что такое корректно работающая программа.
Здесь два момента.
  • Процедура нижнего уровня не всегда знает, как реагировать на особую ситуацию, т.к. может вызываться в разных обстоятельствах, для которых и решения требуются разные.
  • Глубина вызовов. Ошибка (или особая ситуация) может случиться где-то "на дне" стека вызовов. Особенно это существенно для программ с рекурсией, вроде синтаксического разбора. У меня была недавно такая ситуация при написании DLL на Си++. Там я использовал выброс исключения. В старом Паскале я бы использовал goto (да-да, но только для этого! :) ). В ББ непонятно, что надо было бы в подобной ситуации использовать (именно при написании DLL).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 14:20 

Зарегистрирован: Вторник, 20 Ноябрь, 2007 10:45
Сообщения: 28
Здравствуйте.
Я читаю форум уже продолжительное время, однако до этого момента сказать было нечего, а читать - интересно ;), так что это моё первое сообщение здесь.

Цитата:
Мне кажется, что механизм исключений размывает, делает нечётким представление о том, что такое корректно работающая программа. Когда говорят, что данная процедура при корректных входных параметрах может либо вернуть значение в OUT-параметре, либо выбросить исключение EDivByZero, то мне представляется, что разработчики при проектировании не потрудились подумать головой и сделать осмысленный интерфейс. Ведь чем более низкоуровневое исключение я "поймал" наверху, тем меньше у меня информации о том, где и почему оно возникло, как мне избежать его в дальнейшем, и что мне в этой связи показать пользователю. Тем более, что все эти исключения могут добавляться, изменяться и удаляться без малейшего изменения программного интерфейса, и вообще в этой связи не являются частью контракта. : (


Я считаю исключения скорее полезными чем нет. Если разрабатываемый вами протокол зависит от другого протокола, например, получает объект, реализующий протокол, в качестве параметра метода, то вы не можете быть уверены в его безошибочной реализации. Или, наоборот, если ваш компонент, реализующий какой-либо протокол, используется с нарушениями контракта - вызывается метод с фактическими параметрами, которые ваш компонент не может обработать, то разумно выбросить исключение из реализации вызываемого метода.

Я достаточно долго программирую с претензией на ООП ;) Знаком с большинством "мэйнстрим'овых" языков (к сожалению oberon семейство прошло мимо меня :( ), и на данный момент выработал следующие правила проектирования и использования исключений.

  • eсли в языке есть конструкторы/деструкторы то они не должны выбрасывать исключения;
  • исключение может выбросить только метод протокола (интерфейса);
  • с каждым протоколом (интерфейсом) связан свой тип исключения, например SomeProto - SomeProtoException, и этот тип должен быть наследником базового типа исключения;
  • если какой-то метод протокола может выбросить несколько типов исключений, то эти типы должны быть в одной иерархии и корневой тип этой иерархии (не считая базового типа всех исключений) - тип исключения связанного с протоколом (см. вложение);
  • иерархию типов исключений проектирует всегда разработчик протокола, а не разработчик реализации;
  • при возникновении исключения которое не может быть корректно обработано - при раскрутке стека - низкоуровневое исключение всегда оборачивается в исключение более высокого уровня так чтобы можно было получить доступ ко всей цепочке.

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


Вложения:
исключения протокола.png
исключения протокола.png [ 8.38 КБ | Просмотров: 8949 ]
Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 14:32 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
AVC писал(а):
Процедура нижнего уровня не всегда знает, как реагировать на особую ситуацию, т.к. может вызываться в разных обстоятельствах, для которых и решения требуются разные.
Если это аргумент в пользу исключений, то я его не понял. Да, процедура должна выставить некий признак сбоя (вернуть FALSE или один из кодов ошибки, описанный в разделе CONST), а объемлющий код должен обработать его в соответствии с контекстом вызова. Это всё можно сделать в пределах контракта, не прибегая к исключениям.
Да, чем более высок уровень, на котором мы анализируем ситуацию, тем больше слоёв вглубь может потребоваться пройти, чтобы определить конкретную причину сбоя (если это действительно нужно), но разве исключение упрощает эту работу? По-моему, не очень.
AVC писал(а):
Глубина вызовов. Ошибка (или особая ситуация) может случиться где-то "на дне" стека вызовов. Особенно это существенно для программ с рекурсией, вроде синтаксического разбора. У меня была недавно такая ситуация при написании DLL на Си++. Там я использовал выброс исключения. В старом Паскале я бы использовал goto (да-да, но только для этого! :) ). В ББ непонятно, что надо было бы в подобной ситуации использовать (именно при написании DLL).
Вот этот аргумент я, кажется, понял. В самом деле, исключение - это goto сквозь стек вызовов, при этом несущее некий идентификатор ошибки (Delphi, например, использует этот идентификатор для хранения указателя на объект типа Exception, в котором есть дополнительные поля для текста сообщения и т.п., но изначально этот всё тот же числовой код ошибки, который положено было предусмотреть в контракте). Единственная причина использовать этот неструктурный оператор, на мой взгляд, заключается в том, что изначально при проектировании не был предусмотрен механизм "отступления", отката. В этой связи интересный вопрос вот в чём. Оберон-культура стимулирует защитное программирование, опирающееся на постулат "программисты ошибаются". Отсюда требование читабельности программ, строгая типизация, использование ASSERT для проверки контрактов и прочее. А как быть с ошибками проектирования? Что если у нас такая замороченная рекурсия, что выйти из неё только через goto? Тут, похоже язык программирования бессилен. Но означает ли это, что "Гордиев узел" можно разрубить только с помощью goto?

Что касается примера с парсером, то я и сам немного парсерами занимался, поэтому спрошу вот что. Любой парсер должен уметь обработать неожиданный конец данных (в некотором смысле это - исключительная ситуация, не так ли?). Все циклы парсера обычно пишутся с оглядкой на признак eof. Неужели нельзя было при необходимости прерывания разбора сымитировать eof? Выставили бы внутри модуля соответствующий флаг, что eof не настоящий, а на самом деле ошибка в другом. Стек бы раскрутился сам собой до начальной точки, а там бы уже и проанализировали...?

Или вы и конец данных готовы были только как exception чтения ловить? Ну, тогда извините, вариантов нет. Как известно, структурированную программу всегда можно переписать с помощью goto, но обратное неверно. Если вы изначально полагаетесь на исключения, то отказаться от них может быть невозможно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 14:49 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Geniepro писал(а):
info21 продемонстрировал свою фирменную и неудержимую страсть к переходам на личности. Всё правильно... :lol:

Паттерн: "Защита клеветника".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 14:59 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Александр Ильин писал(а):
... Оберон-культура стимулирует защитное программирование, опирающееся на постулат "программисты ошибаются".
Отсюда требование читабельности программ, строгая типизация, использование ASSERT для проверки контрактов и прочее.

Браво. Оберон-культура. Еще лучше, чем Оберон-технологии.
Но тут в самом деле некая культура.

Александр Ильин писал(а):
А как быть с ошибками проектирования? Что если у нас такая замороченная рекурсия, что выйти из неё только через goto? Тут, похоже язык программирования бессилен.

Да уж. Язык, вправляющий мозги проектировщику, это дело отдалённого пока будущего :)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 15:22 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Илья Ермаков писал(а):
Если метод Close не вызван явно, его вызовет финализатор при сборе мусора.


Я бы в таком случае ожидал диагностическое сообщение. "Метод Close не был вызван, хотя изначально предполагается, что в корректной программе он будет вызван". Насколько я знаю в C# есть возможность такой диагностики.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 15:46 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Александр Ильин писал(а):
Мне кажется, что механизм исключений размывает, делает нечётким представление о том, что такое корректно работающая программа. Когда говорят, что данная процедура при корректных входных параметрах может либо вернуть значение в OUT-параметре, либо выбросить исключение EDivByZero, то мне представляется, что разработчики при проектировании не потрудились подумать головой и сделать осмысленный интерфейс.


Вполне осмысленные интерфейс - аргументы отдельно, результат отдельно, ошибки отдельно. Ошибка не замазана в результат или в аргументы.

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


А не надо ничего показывать. Надо залогать все что можно и тихонько умереть/перезапуститься с извинениями перед пользователем. После чего изучить логи и написать правильную обработатку этой ошибки на нужном уровне. Или, по вашему, пусть лучше пользователь видит окошко трапа от ASSERT'a? :) Или, по вашему, ситуация, когда вы "наверху" получаете "неизвестный" код ошибки чем-то лучше? Кстати, в этом случае информации о том, где и почему эта ошибка возникла у вас еще меньше, чем в случае пойманного исключения.

Александр Ильин писал(а):
Тем более, что все эти исключения могут добавляться, изменяться и удаляться без малейшего изменения программного интерфейса, и вообще в этой связи не являются частью контракта. : (


И это правильно. Потому что это позволяет прозрачно пропускать ошибки через компоненту, которая о них ничего не знает и не должна знать. Кстати, в джаве исключения являютмя частью программного интерфейса. Но там есть средства "отключения" такого контроля.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 15:51 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
MaximGB писал(а):
Здравствуйте. Я читаю форум уже продолжительное время, однако до этого момента сказать было нечего, а читать - интересно ;), так что это моё первое сообщение здесь.
Добро пожаловать : )
MaximGB писал(а):
Я считаю исключения скорее полезными чем нет. Если разрабатываемый вами протокол зависит от другого протокола, например, получает объект, реализующий протокол, в качестве параметра метода, то вы не можете быть уверены в его безошибочной реализации. Или, наоборот, если ваш компонент, реализующий какой-либо протокол, используется с нарушениями контракта - вызывается метод с фактическими параметрами, которые ваш компонент не может обработать, то разумно выбросить исключение из реализации вызываемого метода.
Согласитесь, Максим, что механизм исключений не является необходимым для реализации подобных отношений между объектами. Достаточно в самом базовом объекте предусмотреть поле error c числовым значением ошибки. Теперь далее:
MaximGB писал(а):
при возникновении исключения которое не может быть корректно обработано - при раскрутке стека - низкоуровневое исключение всегда оборачивается в исключение более высокого уровня так чтобы можно было получить доступ ко всей цепочке. В последнем пункте под высокоуровневым я имею в виду исключение выбрасываемое в методе выше по стеку.
В целом ваш подход мне представляется очень правильным, и я благодарен вам за то, что вы его описали, иначе нечто подобное пришлось бы писать мне. Однако, обратите внимание: при таком правильном, структурном подходе к проектированию и реализации системы исключительных ситуаций получается, что исключение в любом случае обрабатывается, даже если оно будет проигнорировано. В том смысле, что для всякого исключения есть программный код, который его поймает и обернёт исключением другого типа. Насколько я понимаю, главный аргумент за использование исключений состоит в том, что если нет сильного желания, то можно не возиться с кодами ошибок - мол, оно само допрыгнет до обработчика. В вашем же варианте возня с кодами (if obj.error <> OK...) заменена на аналогичную возню с прыгающими блохами (except on E:Exception do raise MyException.Create(E)...). Фактически вы вручную минимизировали дистанцию прыжка - по границам объектов. Есть ли тогда смысл?

Если есть желаение получить именно цепочку ошибок, то достаточно иметь простую библиотечку, где это всё можно регистрировать при обработке if obj.error <> OK. Примитивный вариант такой библиотеки - текстовый журнал событий (либо лог-файл), но можно сделать и объектно-ориентированную реализацию для упрощения анализа и обработки ошибок изнутри самой программы - и "получить доступ ко всей цепочке". Нужен ли такой механизм в языке программирования (не как библиотека, а как часть языка, зашитая в компилятор)? У меня очень большие сомнения на этот счёт.

Итак, можно подвести промежуточный итог. Исключения - это:
1. goto через стек вызовов процедур;
2. средство обработки ошибок;
3. средство отделения полезного кода от кода обработки особых случаев (последний переносится в блоки except либо finally, по сути не отличающиеся от IF/ELSIF/ELSE);
4. средство оптимизации за счёт исключения лишних проверок из полезного кода.

На мой взгляд, (2) и (3) достижимо библиотечными средствами и соглашениями наподобие вашей системы правил пользования исключениями, а (1) и (4) скорее способствует разгильдяйству при программировании, чем помогает решать реальные проблемы. Где-то здесь пролегает тонкая грань между признанием того, что "программисты ошибаются", и признанием собственного бессилия. Я ожидаю исключение при вызове метода чужого объекта в том случае, если я исхожу из того, что автор объекта - дурак, править его код невозможно, добиваться, чтобы он сам его исправил, тоже бессмысленно, а написать свой такой же объект я не могу. Остаётся только поймать исключение и сказать: "Это он дурак, а не я!" Как вы понимаете, на уровне языка программирования это не решается, это проблема из другой плоскости. Так же, как многозадачность в современных ОС: одна программа может сломаться, но другие не должны пострадать. Ввод в язык механизма исключений ничего не решает, а только лишь добавляет новые организационные проблемы.

Вот что действительно важно - это понимать и уметь организовывать обработку ошибок. Этот механизм тоже нужно проектировать, как канализацию в многоквартирном доме. Просто мало кто считает это самостоятельной проблемой. Не в том смысле, что "мараться не хочется", а в том смысле, что наибольший интерес вызывает основная задача -планировка и интерьер. А ведь при обработке ошибок наверняка тоже есть свои паттерны проектирования. Есть коды ошибок, возвращаемые процедурой или устанавливаемые в глобальной переменной модуля, есть журналы и лог-файлы, есть объекты с текстом (Exception) и т.п. Есть механизмы заменяемые, когда с ростом проекта один механизм можно заменить на другой, а есть статичные, которые трудно поддаются корректировке. Хотелось бы как-то эту тему копнуть поглубже.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 16:00 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Александр Ильин писал(а):
Все циклы парсера обычно пишутся с оглядкой на признак eof.


Нет. В том-то и дело, что с оглядкой на eof пишутся только те циклы, где достижение этого eof является корректной ситуацией. И это здорово все упрощает.

Александр Ильин писал(а):
Неужели нельзя было при необходимости прерывания разбора сымитировать eof? Выставили бы внутри модуля соответствующий флаг, что eof не настоящий, а на самом деле ошибка в другом. Стек бы раскрутился сам собой до начальной точки, а там бы уже и проанализировали...?


Ужас какой. И такой жуткий хак предлагает оберонщик? :)

Александр Ильин писал(а):
Или вы и конец данных готовы были только как exception чтения ловить? Ну, тогда извините, вариантов нет. Как известно, структурированную программу всегда можно переписать с помощью goto, но обратное неверно. Если вы изначально полагаетесь на исключения, то отказаться от них может быть невозможно.


А вот здесь вы правы. Надо писать или "с" или "без" исключений. Потому что "среднее" сопровождать будет невозможно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 16:17 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Александр Ильин писал(а):
В вашем же варианте возня с кодами (if obj.error <> OK...) заменена на аналогичную возню с прыгающими блохами (except on E:Exception do raise MyException.Create(E)...). Фактически вы вручную минимизировали дистанцию прыжка - по границам объектов. Есть ли тогда смысл?


Смысл в том, что "возня" осуществляется не после вызова каждой функции, и на границах слоев системы (даже не модулей). Разница в количестве затуманивающей код писанины из мнгократно вложенных IF/ELSE - на порядки.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 17:13 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
Vlad писал(а):
с оглядкой на eof пишутся только те циклы, где достижение этого eof является корректной ситуацией. И это здорово все упрощает.
Ну, не знаю, это тоже вопрос проектирования. Вот, например, мой частичный парсер Оберона. Использует модуль сканера OPS (Oberon Portable Scanner). Чтение символа: OPS.Read (sym). Одно из возможных значений sym = OPS.eof - сигнализирует достижение конца файла. Большинство циклов в парсере имеют один из двух видов: WHILE sym = OPS.ident DO либо WHILE (sym # OPS.semicolon) & (sym # OPS.eof) DO. Во втором случае проверка eof обязательно должна присутствовать, иначе это просто ошибка, ведущая к зацикливанию в определённых ситуациях. Поможет ли исключение избежать зацикливания? Возможно, если исключением считать повторный вызов OPS.Read после возвращения sym = OPS.eof. Но тогда зачем вообще возвращать eof? Дублирование получается: два способа сообщить об одном и том же событии - окончании входного потока. Я исхожу из того, что дублирование - это плохо, поскольку вносит неопределённость и, тем самым, увеличивает сложность системы. Есть чтение после конца потока - есть однозначная реакция на такое чтение. По поводу исключений: если я уже и так пишу алгоритм разбора (парсер), то зачем мне надстраивать над этим ещё какой-то мета-аглоритм для прекращения разбора? Разве это не один и тот же алгоритм? (Прям даосизм какой-то начинается.)
Vlad писал(а):
Ужас какой. И такой жуткий хак предлагает оберонщик? :)
Я предлагаю сразу проектировать правильно : ) А по поводу данного примера, то в пределах своего модуля я имею право считать, что eof - это не физический конец файла, а логический конец обработки данных моим модулем. В конце концов, переменная sym не видна извне, и её значение я определяю по своему усмотрению.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 18:26 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
А где Вы нашли eof? Я в BB находил пока только eot, что как раз и обозначает то, о чём Вы сказали: разбор текста закончился (или разбираемый текст, соответствующий заявленной структуре, закончился).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 18:29 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1466
Откуда: Киев
Считаю, что исключения нужны.
Расскажу об одной задаче, где мне пришлось их использовать, поскольку я не видел адекватного по сложности способа обойтись без них .

Есть функция 6-ти переменных, сложная для анализа и затратная по времени вычисления. Если во время вычисления происходит переполнение одной из временных переменных, значит значение функции для задачи не важно и можно считать его неопределённым. Промежуточных действий в функции много и перед каждым из них анализировать возможность переполнения лень, к тому же функция немаленькая и ошибиться при этом анализе очень просто. Также необходимо минимизировать время вычисления этой функции. С механизмом исключений всё просто - при переполнении возвращаем значение, означающее неопределённость. А как без него?

П.С.: С тем, что частое использование исключений где ни попадя наносит вред, я согласен.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 18:35 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Александр Ильин писал(а):
Чтение символа: OPS.Read (sym). Одно из возможных значений sym = OPS.eof - сигнализирует достижение конца файла.


Поймите меня правильно :) Я не предлагаю использовать исключения для обработки eof. Я предлагаю использовать исключения для того для чего они предназначены - для обработки ошибок. Конкрено eof в зависимости от контекста может быть ошибкой, а может быть ожидаемым токеном. Конкретно в упомянутой компоненте OPS - eof всего лишь один из токенов. Теперь представьте, что вы парсите конструкцию WHILE и вызываете функцию parse_condition, которая парсит условие. Ожидать, что функция parse_condition вернет eof - это замусоривание кода, потому что в нормальной ситуации такого быть не может, а ненормальную вы хотите явно обработать как ненормальную и скорее всего где-то выше.

Александр Ильин писал(а):
А по поводу данного примера, то в пределах своего модуля я имею право считать, что eof - это не физический конец файла, а логический конец обработки данных моим модулем. В конце концов, переменная sym не видна извне, и её значение я определяю по своему усмотрению.


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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 21 Октябрь, 2008 18:44 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2461
Откуда: Россия, Томск
Valery Solovey писал(а):
А где Вы нашли eof? Я в BB находил пока только eot, что как раз и обозначает то, о чём Вы сказали...
OPS - модуль сканера из Native Oberon.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 178 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 9  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2025, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB