Die Programmiersprache Ruby (German Edition)
ausschließlich, um den Codeblock zu begrenzen, in dem Ausnahmen behandelt werden sollen. Eine
begin
-Anweisung mit einer
rescue
-Klausel sieht so aus:
begin
# Eine beliebige Anzahl von Ruby-Anweisungen
# kann hier stehen. Üblicherweise werden sie
# ohne Ausnahmen ausgeführt, und die Ausführung
# geht nach der end-Anweisung weiter.
rescue
# Dies ist die rescue-Klausel; Ausnahmebehandlungscode kommt
# hierhin. Wenn eine Ausnahme durch den obigen Code ausgelöst
# wird oder aus einer der aufgerufenen Methoden nach oben weiter-
# gegeben wird, springt die Ausführung an diese Stelle.
end
5.6.3.1 Die Bezeichnung des Ausnahmeobjekts
In einer
rescue
-Klausel bezieht sich die globale Variable
$!
auf das zurzeit behandelte
Exception
-Objekt. Das Ausrufezeichen ist eine Merkhilfe: Eine Ausnahme ähnelt gewissermaßen einem Aufruf. Wenn Ihr Programm die Zeile
require 'English'
enthält, können Sie stattdessen die globale Variable
$ERROR_INFO
verwenden.
Eine bessere Alternative zu
$!
oder
$ERROR_INFO
ist die Angabe eines Variablennamens für das Ausnahmeobjekt in der
rescue
-Klausel selbst:
rescue => ex
Die Anweisungen dieser
rescue
-Klausel können nun die Variable
ex
verwenden, um Bezug auf das
Exception
-Objekt zu nehmen, das die Ausnahme beschreibt, zum Beispiel:
begin # Ausnahmen in diesem Block behandeln
x = factorial(-1) # Beachten: illegales Argument
rescue => ex # Ausnahme in Variable ex speichern
puts "#{ex.class}: #{ex.message}" # Ausnahme durch Meldung behandeln
end # Ende des begin/rescue-Blocks
Beachten Sie, dass eine
rescue
-Klausel keinen neuen Variablen-Gültigkeitsbereich definiert und dass eine in der
rescue
-Klausel genannte Variable auch nach dem Ende der
rescue
-Klausel noch sichtbar ist. Wenn Sie eine Variable für die
rescue
-Klausel verwenden, dann kann ein Ausnahmeobjekt sichtbar sein, nachdem die
rescue
-Klausel beendet ist, selbst wenn $! nicht mehr gesetzt ist.
5.6.3.2 Ausnahmen nach Typ behandeln
Die hier gezeigten
rescue
-Klauseln behandeln jegliche Ausnahme, die ein
StandardError
(oder eine seiner Unterklassen) ist und ignorieren jedes
Exception
-Objekt, das kein
StandardError
ist. Wenn Sie Nicht-Standard-Ausnahmen außerhalb der
StandardError
-Hierarchie oder nur spezifische Arten von Ausnahmen behandeln möchten, müssen Sie eine oder mehrere Ausnahmeklassen in die
rescue
-Klausel einfügen. Hier sehen Sie, wie Sie eine
rescue
-Klausel schreiben würden, die jede Art von Ausnahmen behandelt:
rescue Exception
Hier sehen Sie, wie Sie eine
rescue
-Klausel zum Behandeln einer
ArgumentError
-Ausnahme schreiben und das Ausnahmeobjekt der Variable
e
zuweisen würden:
rescue ArgumentError => e
Erinnern Sie sich, dass die weiter oben definierte Methode
factorial
einen
ArgumentError
oder
TypeError
auslösen kann. Hier sehen Sie, wie wir eine
rescue
-Klausel schreiben würden, die Ausnahmen beider Typen behandelt und das Ausnahmeobjekt der Variablen
error
zuweist:
rescue ArgumentError, TypeError => error
Hier sehen wir schließlich die Syntax der
rescue
-Klausel in ihrer allgemeinsten Form. Auf das Schlüsselwort
rescue
folgen null oder mehr kommaseparierte Ausdrücke, die jeweils ein Klassenobjekt ergeben müssen, das die Klasse Exception oder eine ihrer Unterklassen repräsentiert. Auf diese Ausdrücke folgen optional
=>
und ein Variablenname.
Nehmen wir nun an, wir möchten sowohl
ArgumentError
als auch
TypeError
behandeln, aber jede der beiden Ausnahmen auf unterschiedliche Weise. Wir könnten eine
case
-Anweisung verwenden, um je nach Klasse des Ausnahmeobjekts unterschiedlichen Code auszuführen. Es ist jedoch eleganter, einfach mehrere
rescue
-Klauseln zu verwenden. Eine
begin
-Anweisung kann null oder mehr von ihnen haben:
begin
x = factorial(1)
rescue ArgumentError => ex
puts "Versuchen Sie es mit einem Wert >= 1"
rescue TypeError => ex
puts "Versuchen Sie es mit einem Integer"
end
Beachten Sie, dass der Ruby-Interpreter versucht, die Ausnahmen den
rescue
-Klauseln in der Reihenfolge zuzuordnen, in der sie geschrieben werden. Deshalb sollten Sie Ihre spezifischsten Ausnahmeunterklassen zuerst hinschreiben und erst danach allgemeinere Typen behandeln. Wenn Sie
EOFError
beispielsweise anders behandeln möchten als
IOError
, stellen Sie sicher, dass Sie die
rescue
-Klausel für
EOFError
an den Anfang stellen, weil der
IOError
-Code diese Ausnahme sonst behandeln wird. Wenn Sie eine »Catch-All«-
rescue
-Klausel haben möchten, die alle noch nicht von vorherigen
Weitere Kostenlose Bücher