next up previous
Nächste Seite: Objekt-orientierte Ausnahmenbehandlung Aufwärts: Ausnahmenbehandlungen Vorherige Seite: Mechanismen für Ausnahmenbehandlungen

Charakterisierung von Ausnahmen

Es gibt verschiedene Ansätze, Ausnahmen zu benennen und zu parametrisieren. Ada unterstützt nur einfache Namen analog zu Variablennamen:

my_exception: exception;
-- ...
raise my_exception;

Bei CLU und Modula-3 kommen nur noch Parameter hinzu, die die Ausnahme näher beschreiben.

Dies ist jedoch unzureichend, da damit ein flacher Namensraum gegeben ist, der nicht weiter strukturiert werden kann. So ist es nicht möglich, alle Ausnahmen abzufangen, die zu einem bestimmten Bereich gehören (z.B. Ausnahmen im Ein- und Ausgabebereich), es sei denn durch das explizite Aufzählen aller Möglichkeiten. Dies führt dazu, daß bei Erweiterungen der Liste der Ausnahmen zahlreiche Listen ergänzt werden müssen. Natürlich ist es möglich, sich auf ganz wenige Typen von Ausnahmen zu beschränken, die dann nur noch über Parametrisierungen weiter spezifiziert werden.

Abbildung: Beispiel für eine Hierarchie von Ausnahmen
\begin{figure}\epsfig{file=ausnahme-hier.eps}\end{figure}

Im Bereich objekt-orientierter Sprachen liegt es jedoch nahe, eine Typenhierarchie für Ausnahmen aufzubauen. Entsprechend kann auf der einen Seite eine sehr detaillierte Information über die Ausnahme generiert werden, die an anderer Stelle gemäß der dortigen Sicht und Interessenslage projiziert wird. Abbildung 5.3.4 zeigt, wie eine solche Hierarchie aussehen könnte. Im Beispiel könnte RuntimeException Angaben über das Modul und die Zeile in der Quelle enthalten, bei der der Fehler aufgetreten ist. Bei der Erweiterung RangeCheckException könnten dann weitere Informationen über den zulässigen Bereich und den Wert des aus dem Bereich fallenden Index angegeben werden. Beim Basistyp Exception könnten Informationen darüber aufgenommen werden, ob eine Fortsetzung (resumption) möglich ist, oder ob eine Terminierung des Signalgebers zwingend ist.

Da Oberon keine Sprachkonstrukte für Ausnahmenbehandlungen offeriert, liegt es nahe, Ausnahmen als Ereignisse zu betrachten. Ereignisse können hierarchisch organisiert werden und jede Information tragen, die von Interesse sein könnte. Hinzu kommt, daß Ereignisse bereits eine Textkomponente besitzen, die für Fehlermeldungen benutzt werden kann.

Ereignisse unterstützen in der bislang vorgestellten Form im wesentlichen nur globale Ausnahmenbearbeiter. Folgendes Beispiel zeigt dies:

DEFINITION SomeModule;

   IMPORT Events;

   CONST
      xxxFailed = 0; yyyFailed = 1; (* ... *)
   TYPE
      ErrorEvent = POINTER TO ErrorEventRec;
      ErrorEventRec =
         RECORD
            (Events.EventRec)
            code: INTEGER; (* xxxFailed etc. *)
            (* Komponenten mit weiteren Informationen *)
         END;
   VAR
      error: Events.EventType;

   PROCEDURE SomeOperation(....) : BOOLEAN;
      (* initiiere `exception' und liefere FALSE zurueck bei Ausfaellen *)

END SomeModule.

Ereignisse werden vielfach ignoriert und es ist häufig umständlich, Fehlersituationen auf diese Weise zu notieren. Daher liegt es nahe, daß SomeOperation nach der Auslösung der Ausnahmenbehandlung mit FALSE als Rückgabewert beendet wird. BOOLEAN-Rückgabewerte sind besonders praktisch, da sie einerseits die Verknüpfung einer Reihe von Operationen mit dem Und-Operator (in Oberon &) erlauben und zum anderen nicht versehentlich ignoriert werden können. Die Implementierung würde dann folgendermaßen aussehen:

MODULE SomeModule;

   (* ... *)

   PROCEDURE Error(code: INTEGER; ...);
      VAR
         event: ErrorEvent;
   BEGIN
      NEW(event); event.type := error;
      event.message := (* etwas in Abhaengigkeit von `code' *);
      event.code := code;
      (* Ausfuellen weiterer beschreibender Komponenten *)
      Events.Raise(event);
   END Error;

   PROCEDURE SomeOperation(...) : BOOLEAN;
   BEGIN
      (* ... *)
      IF (* Ausfall entdeckt *) THEN
         Error(...); RETURN FALSE
      END;
      (* ... *)
      RETURN TRUE
   END SomeOperation;

BEGIN
   Events.Define(error);
END SomeModule.

Diese Lösung ist jedoch normalerweise unzureichend, da es schwierig ist, die Ausnahme zu dem Klienten und den Parametern von SomeOperation in Bezug zu setzen. Zwar erfährt der Klient über den Rückgabewert, daß SomeOperation fehlschlug, doch es erscheint sehr umständlich, dem Klienten oder dem zugehörigen Objekt mehr Informationen zugänglich zu machen. Hierfür wäre es notwendig, temporäre Interessenten für die potentiellen Ausnahmeereignisse anzugeben, die dann trotzdem immer noch Schwierigkeiten hätten, die Zuordnung durchzuführen. Dies würde wohl entsprechende globale Variablen unvermeidbar machen.


next up previous
Nächste Seite: Objekt-orientierte Ausnahmenbehandlung Aufwärts: Ausnahmenbehandlungen Vorherige Seite: Mechanismen für Ausnahmenbehandlungen
Andreas Borchert 2000-12-18