Hemos visto cómo diversas situaciones excepcionales provocan la
aparición de una ventana de depuración. De hecho, las excepciones
(Exception) también son objetos que recuerdan su contexto y
pueden presentarlo. Anteriormente, hemos visto cómo generar instancias
de excepción MessageNotUnderstood y ZeroDivide.
Esta es otra área en la que la mecánica real es compleja, pero las ideas básicas son sencillas.
Las instancias de excepciones, al ser objetos, también tienen clases. El
BlockClosure tiene una categoría de métodos exceptions
que reúne algunos métodos útiles que permiten ensure: limpiar o
capturar y utilizar excepciones (on:do: y similares).
FileEntry>>readStreamDo: blockWithArg "Raise FileDoesNotExistException if not found." | stream result | stream := self readStream. [ result := blockWithArg value: stream ] ensure: [ stream ifNotNil: [ :s | s close ]]. ^ result
Ejemplo 10.1: Asegurar que un FileStream está cerrado
Se crean y se avisan (signal) excepciones. Creemos una y veámosla.
Figura 10.1: Inspección de una instancia ZeroDivide
Una vez más, podemos usar un Inspector en cualquier objeto, ¡y las
Exceptions no son una excepción! Ahora ya sabes cómo capturar
una cuando lo necesites.
Las Exceptions, al igual que los MorphicEvents,
son un cambio, una excepción, al flujo de control típico.
Anteriormente hemos mencionado la pseudovariable especial
thisContext. La llamada de una excepción captura esto.
Exception>>signal ^ self signalIn: thisContext
Ejemplo 10.2: Capturar thisContext
Al igual que el código Smalltalk tiene ventanas de visualización
especiales que llamamos Browser, las Exception tienen un
visor mejorado que llamamos Debugger. Veamos cómo utilizar este
útil visor.