- •Предисловие
- •Структура классического Смолтока
- •Основные определения и термины
- •Метаклассы
- •Посылка сообщений
- •Определение объектов
- •Типы сообщений и их приоритеты
- •Блоки
- •Переменные
- •Методы и примитивные методы
- •Соглашения о форматировании кода
- •Контрольные вопросы
- •Прогулка по VisualWorks
- •Настройка среды
- •Разработка простого приложения
- •Сохранение созданного кода
- •Создание автономного приложения
- •Выход из среды
- •Контрольные вопросы
- •Пространства имён
- •Особенности введения пространств имён
- •Пространство имён и его содержимое
- •Ссылка на объекты и импорт
- •Особенности импорта
- •Разделяемые переменные VisualWorks 7.4.1
- •Пакеты и парселы
- •Пакеты и связки пакетов
- •Парселы
- •Контрольные вопросы
- •Основные инструменты
- •Рабочее окно
- •Администратор парселов
- •Браузер файлов
- •Контрольные вопросы
- •Cистемный браузер
- •Панели системного браузера
- •Управление пакетами
- •Управление связками пакетов
- •Управление парселами
- •Определение пространства имён
- •Определение класса
- •Определение переменной класса
- •Определение переменных в пространстве имён
- •Работа с экземплярами
- •Определение метода
- •Контрольные вопросы
- •Отладка кода
- •Oкно уведомлений
- •Oкно отладки кода
- •Программные зонды
- •Работа с зондами через браузер
- •Зонды на уровне класса
- •Установка временных зондов в отладчике
- •Исключения и их обработка
- •Классы исключений
- •Обработка исключений
- •Оповещение о возникновении исключения
- •Среда исключений процесса
- •Явный выход из обработчика
- •Преобразование исключений
- •Развертывание защиты
- •Поставка приложения
- •Выбор стратегии поставки
- •Подготовка к поставке приложения
- •Создание поставляемого образа
- •Контрольные вопросы
- •Литература
- •Список иллюстраций
Глава 8
Исключения и их обработка
Исключение (особая ситуация) — необычное или нежелательное событие, которое может происходить во время выполнения приложения. Хотя не все исключения — ошибки, ошибки являются одними из тех наиболее важных исключений, которые должно обрабатывать приложение. Когда возникает исключение, приложение может его перехватывать
ивызывать специальную обработку исключения.
Вверсии VisualWorks 7.4.1 используется механизм обработки особых ситуаций, соответствующий ANSI-стандарту и реализованный через иерархию класса GenericException (ОбщееИсключение). Этот механизм должны использовать все создаваемые приложения.
8.1.Классы исключений
Исключения представляются экземплярами класса Exception и его многочисленных подклассов, наиболее важными из которых являются Error (Ошибка) и Notification (Уведомление). В свою очередь, подклассы этих классов, определяют более специальные виды исключений. При создании приложений и, в случае необходимости, определения новых классов для специальных исключений, новый класс исключения следует создавать как подкласс Error (в ситуации, когда нельзя будет продолжать выполнение приложения), или Notifier (в ситуации, когда выполнение приложения можно будет продолжить).
Исключение работает, сотрудничая с экземпляром класса Signal, который создаёт исключение, когда ему посылается некоторый вариант сообщения #raise. Исключение хранит информацию о природе ошибки
— о сигнале (signal), который создал его, об объекте (originator), который породил его, о параметре исключения (parameter). Приложение может использовать эту информацию, чтобы определить реакцию на исключение, которая может состоять в том, чтобы прервать выполнение
8.2. Обработка исключений |
129 |
операции, продолжить выполнение или перезапустить операцию. Все экземпляры класса Exception и его подклассов отвечают на сообщение description, возвращая строку, которая описывает данное исключение.
Каждый подкласс в Exception или определяет, или наследует сообщение defaultAction, которое вызывается тогда, когда данное исключение происходит, если явно не вызывается другое сообщение. Создавая приложение, можно создавать новые подклассы исключений и, если потребуется, специальные методы их обработки (обработчики) (см. в последующих разделах).
Перечислим общие классы исключений, указывая особое событие, представляемое этим классом, и выполняемое по умолчанию действие.
Таблица 8.1: Классы исключений и их действия по умолчанию
Класс иск- |
Событие исключения |
|
Действие по умолчанию |
|||||||
лючения |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
ArithmeticEr- |
Любая |
ошибка, |
возни- |
Наследуется |
из |
класса |
||||
ror |
кающая |
при |
вычисле- |
Error. |
|
|
|
|||
|
нии арифметической опе- |
|
|
|
|
|||||
|
рации. |
|
|
|
|
|
|
|
|
|
Error |
Любая ошибка програм- |
Открыть окно уведомле- |
||||||||
|
мы. |
|
|
|
|
|
ний. |
|
|
|
MessageNot- |
Сообщение |
было |
посла- |
Наследуется |
из |
класса |
||||
Understood |
но объекту, который |
не |
Error. |
|
|
|
||||
|
определяет |
соответству- |
|
|
|
|
||||
|
ющего метода. |
|
|
|
|
|
|
|
||
Notification |
Любое |
необычное |
собы- |
Ничего не делать, про- |
||||||
|
тие, которое |
не |
вредит |
должить выполнение. |
||||||
|
выполнению программы. |
|
|
|
|
|||||
Warning |
Необычное |
событие, |
о |
Задать вопрос, |
предпо- |
|||||
|
котором |
|
пользователь |
лагающий |
ответ |
Yes/No |
||||
|
должен знать. |
|
|
|
(Да/Нет) |
и |
возвратить |
|||
|
|
|
|
|
|
|
логическое значение. |
|||
ZeroDivide |
Попытка |
деления |
на |
Наследуется |
из |
класса |
||||
|
нуль. |
|
|
|
|
|
ArithmeticError. |
|
||
|
|
|
|
|
|
|
|
|
|
|
8.2.Обработка исключений
Обработка по умолчанию большинства исключений приводит к отображению окна уведомления. В многих ситуаций этого достаточно. Когда же для обработки исключения требуется действие, отличное от действия по умолчанию, нужно определить свой обработчик исключения.
130 |
Глава 8. Исключения и их обработка |
Обработчик исключения определяется через сообщение on:do:. Первый аргумент — класс исключения, за которым наблюдает обработчик. Второй аргумент — блок кода (блок обработки), который выполняется тогда, когда происходит данное исключение. Блок обработки — блок с одним аргументом. Экземпляр класса произошедшего исключения передается блоку обработки как аргумент.
Например, следующий код определяет обработчик для исключения, возникающего при попытке деления на нуль, который печатает информационное сообщение в виде строки, отображаемой в окне Transcript:
-1.0 to: 1.0 do: [ :i |
[ 10.0/i. Transcript cr; show: i printString] on: ZeroDivide
do: [:ex | Transcript cr; show: ’divideByZero’.]
].
В окне Transcript будет отображена следующая информация:
-1.0 divideByZero 1.0
Обработчик исключения обычно завершает свою работу, возвращая значение блока обработки, вместе значения блока приемника (защищенного блока). Если в дополнение к возвращению значения из блока обработки, надо ещё и выйти из метода, содержащего этот блок, то, как и в случае любого другого блока, следует использовать оператор возврата значения.
-1.0 to: 1.0 do: [ :i |
[ 10.0/i. Transcript cr; show: i printString] on: ZeroDivide
do: [:ex | Transcript cr; show: ’divideByZero’. ^ ’divideByZero abort’.]
].
В окне Transcript будет отображена следующая информация:
-1.0 divideByZero
а метод возвратит строку ’divideByZero abort’ и прекратит работу. Вместо точного указания характера исключения, можно указывать
более общее исключение. Например,
[x / y] on: Error do: [:ex | ^ ’divideByZero abort’].
8.2. Обработка исключений |
131 |
В этом примере класс Error определяет то исключение, которое будет обрабатываться вместо исключения ZeroDivide. Тогда, в силу наследования, обработчик будет обрабатывать и исключение Error, и исключение, которое являются экземпляром его подкласса. В данном случае используется уже существующая в VisualWorks иерархия классов
GenericException
Exception
Error ArithmeticError
DomainError ZeroDivide
В примере выше возвращаемая информация минимальна, но вполне достаточна. Однако, вряд ли разумно обрабатывать каждое происходящее исключение, используя выражение, подобное такому:
[. . . некоторый код . . . ] on: Exception
do: [:ex | Transcript show: ’An exception occurred’; cr.]
Класс Exception является слишком общим, и при таком коде приложение будет так отвечать на все исключения, включая обращения к объектам Notification, которые никак не влияют на выполнение приложения.
Обработчик исключения может автоматически получать информацию о том исключении, с которым он имеет дело:
-1.0 to: 1.0 do: |
|
[ :i | |
|
[ 10.0/i. Transcript cr; show: i printString] |
|
on: Error |
|
do: [:ex | Transcript cr; show: ex description.] |
]. |
В этом случае в окне Transcript будет отображена информация, учитывающая строку, возвращаемую возникшим исключением по сообщению description:
-1.0
Can’t divide a number by zero 1.0
Иногда нужно установить обработчик исключений так, чтобы он обрабатывал несколько исключений, которые не обязательно входят в одну ветвь иерархии. Это можно сделать, используя класс ExceptionSet. Если происходит исключение из указанных классов или их подклассов, активизируется блок обработки. Можно неявно создавать множество исклю-