КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Восстановление при исключениях, сгенерированных операционной системой
Поломки при вводе Примеры обработки исключений
Теперь, когда у нас есть базисный механизм, давайте посмотрим, как он применяется в общих ситуациях.
Предположим, что в интерактивной системе необходимо выдать подсказку пользователю, от которого требуется ввести целое. Пусть только одна процедура занимается вводом целых - read_one_integer, которая результат ввода присваивает атрибуту last_integer_read. Эта процедура работает неустойчиво, - если на ее входе будет нечто, отличное от целого, она может привести к отказу, выбрасывая исключение. Конечно, вы не хотите, чтобы это событие приводило к отказу всей системы. Но поскольку вы не управляете программой ввода, то следует ее использовать и организовать восстановление ситуации, при возникновении исключений. Вот возможная схема:
get_integer is -- Получить целое от пользователя и сделать его доступным в -- last_integer_read. -- Если ввод некорректен, запросить повторения, столько раз, -- сколько необходимо. do print ("Пожалуйста, введите целое: ") read_one_integer rescue retry end
Эта версия программы иллюстрирует стратегию повторения. Очевидный недостаток - пользователь упорно вводит ошибочное значение, программа упорно запрашивает значение. Это не очень хорошее решение. Можно ввести верхнюю границу, скажем 5, числа попыток. Вот пересмотренная версия:
Maximum_attempts: INTEGER is 5 -- Число попыток, допустимых при вводе целого. get_integer is -- Попытка чтения целого, делая максимум Maximum_attempts попыток. -- Установить значение integer_was_read в true или false -- в зависимости от успеха чтения. -- При успехе сделать целое доступным в last_integer_read. local attempts: INTEGER do if attempts < Maximum_attempts then print ("Пожалуйста, введите целое: ") read_one_integer integer_was_read:= True else integer_was_read:= False end rescue attempts:= attempts + 1 retry end
Предполагается, что включающий класс имеет булев атрибут integer_was_read. Вызывающая программа должна использовать эту программу следующим образом, пытаясь введенное целое присвоить сущности n:
get_integer if integer_was_read then n:= last_integer_read else "Иметь дело со случаем, в котором невозможно получить целое" end
Среди событий, включающих исключения, есть сигналы, посылаемые операционной системой, некоторые из которых являются следствием аппаратных прерываний. Примеры: арифметическое переполнение сверху и снизу, невозможные операции ввода-вывода, запрещенные команды, обращение к недоступной памяти, прерывания от пользователя (например, нажата клавиша break). Теоретически можно рассматривать такие условия, как нарушение утверждений. Если a+b приводит к переполнению, то это означает, что вызов не удовлетворяет неявному предусловию функции + для целых или вещественных чисел, устанавливающее, что сумма двух чисел должна быть представима в компьютере. Подобное неявное предусловие задается при создании новых объектов (создание копии) - памяти должно быть достаточно. Отказы встречаются из-за того, что окружение - файлы, устройства, пользователи - не отвечают условиям применимости. Но в таких случаях непрактично или невозможно задавать утверждения, допуская их независимую проверку. Единственное решение - пытаться выполнить операцию, и, если аппаратура или операционная система выдает сигнал о ненормальном состоянии, рассматривать его как исключение. Рассмотрим проблему написания функции quasi_inverse, возвращающей для каждого вещественного x обратную величину 1/x или 0, если x слишком мало. Подобные задачи по существу нельзя реализовать, не используя механизм исключений. Единственный практичный способ узнать, можно ли для данного x получить обратную величину, это выполнить деление. Но деление может спровоцировать переполнение, и если нет механизма управления исключениями, то программа завершится отказом, и будет слишком поздно возвращать 0 в качестве результата. На некоторых платформах можно написать функцию invertible, такую что invertible(x) равна true, если и только если обратная величина может быть вычислена. Тогда можно написать и quasi_inverse. Но это решение не будет переносимым, и может приводить к потере производительности при интенсивном использовании этой функции.Механизм rescue-retry позволяет просто решить эту проблему, по крайней мере, на платформе, включающей сигнал при арифметическом переполнении:
quasi_inverse (x: REAL): REAL is -- 1/x, если возможно, иначе 0 local division_tried: BOOLEAN do if not division_tried then Result:= 1/x end rescue division_tried:= True retry end
Правила инициализации устанавливают значение false для division_tried в начале каждого вызова. В теле не нужно предложение else, поскольку инициализация установит Result равным 0.
Дата добавления: 2014-01-07; Просмотров: 353; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |