Ich habe vor kurzem angefangen, in Ruby zu programmieren, und ich beschäftige mich mit der Ausnahmebehandlung.
Ich habe mich gefragt, ob ensure
das Ruby-Äquivalent finally
in C # ist. Sollte ich haben:
file = File.open("myFile.txt", "w")
begin
file << "#{content} \n"
rescue
#handle the error here
ensure
file.close unless file.nil?
end
oder soll ich das machen
#store the file
file = File.open("myFile.txt", "w")
begin
file << "#{content} \n"
file.close
rescue
#handle the error here
ensure
file.close unless file.nil?
end
Does ensure
erhalten egal genannt , was, auch wenn eine Ausnahme nicht erhoben wird?
ruby-on-rails
ruby
exception
exception-handling
error-handling
Lloyd Powell
quelle
quelle
begin
Blocks befindet.Antworten:
Ja,
ensure
stellt sicher, dass der Code immer ausgewertet wird. Deshalb heißt esensure
. Es ist also äquivalent zu Java und C #finally
.Der allgemeine Ablauf von
begin
/rescue
/else
/ensure
/end
sieht folgendermaßen aus:Sie können weglassen
rescue
,ensure
oderelse
. Sie können auch die Variablen weglassen. In diesem Fall können Sie die Ausnahme in Ihrem Ausnahmebehandlungscode nicht überprüfen. (Nun, Sie können immer die globale Ausnahmevariable verwenden, um auf die letzte Ausnahme zuzugreifen, die ausgelöst wurde, aber das ist ein bisschen hackig.) Und Sie können die Ausnahmeklasse weglassen. In diesem Fall werden alle AusnahmenStandardError
abgefangen , von denen geerbt wird. (Bitte beachten Sie, dass dies nicht bedeutet , dass alle Ausnahmen abgefangen werden, denn es gibt Ausnahmen , die Instanzen sindException
aber nichtStandardError
. Meistens ist sehr schwere Ausnahmen , dass ein Kompromiss der Integrität des Programms wieSystemStackError
,NoMemoryError
,SecurityError
,NotImplementedError
,LoadError
,SyntaxError
,ScriptError
,Interrupt
,SignalException
oderSystemExit
.)Einige Blöcke bilden implizite Ausnahmeblöcke. Beispielsweise sind Methodendefinitionen implizit auch Ausnahmeblöcke, anstatt zu schreiben
du schreibst nur
oder
Gleiches gilt für
class
Definitionen undmodule
Definitionen.In dem speziellen Fall, nach dem Sie fragen, gibt es jedoch tatsächlich eine viel bessere Sprache. Wenn Sie mit einer Ressource arbeiten, die Sie am Ende bereinigen müssen, übergeben Sie im Allgemeinen einen Block an eine Methode, die die gesamte Bereinigung für Sie durchführt. Es ähnelt einem
using
Block in C #, nur dass Ruby tatsächlich so mächtig ist, dass Sie nicht darauf warten müssen, dass die Hohepriester von Microsoft vom Berg herunterkommen und ihren Compiler für Sie ändern. In Ruby können Sie es einfach selbst implementieren:Und was wissen Sie: Dies ist bereits in der Kernbibliothek als verfügbar
File.open
. Es ist jedoch ein allgemeines Muster, das Sie auch in Ihrem eigenen Code verwenden können, um jede Art von Ressourcenbereinigung (à lausing
in C #) oder Transaktionen oder was auch immer Sie sonst denken , zu implementieren .Der einzige Fall, in dem dies nicht funktioniert, wenn der Erwerb und die Freigabe der Ressource auf verschiedene Teile des Programms verteilt sind. Wenn es jedoch wie in Ihrem Beispiel lokalisiert ist, können Sie diese Ressourcenblöcke problemlos verwenden.
Übrigens: Im modernen C #
using
ist dies eigentlich überflüssig, da Sie Ressourcenblöcke im Ruby-Stil selbst implementieren können:quelle
ensure
Anweisungen zwar zuletzt ausgeführt werden, jedoch nicht der Rückgabewert sind.ensure
wird angerufen, egal was passiert."Zu Ihrer Information, selbst wenn eine Ausnahme in dem
rescue
Abschnitt erneutensure
ausgelöst wird , wird der Block ausgeführt, bevor die Codeausführung zum nächsten Ausnahmebehandler fortgesetzt wird. Zum Beispiel:quelle
Wenn Sie sicherstellen möchten, dass eine Datei geschlossen ist, verwenden Sie die Blockform von
File.open
:quelle
Ja,
ensure
wird unter keinen Umständen aufgerufen. Weitere Informationen finden Sie unter " Ausnahmen, Fangen und Werfen " im Ruby-Programmierbuch. Suchen Sie nach "Sicherstellen".quelle
Ja, stellt
ensure
sicher , dass es jedes Mal ausgeführt wird, sodass Sie es nichtfile.close
imbegin
Block benötigen .Ein guter Weg zum Testen ist übrigens:
Sie können testen, ob "========= inside sure block" gedruckt wird, wenn eine Ausnahme vorliegt. Dann können Sie die Anweisung auskommentieren, die den Fehler auslöst, und prüfen, ob die
ensure
Anweisung ausgeführt wird, indem Sie prüfen, ob etwas ausgedruckt wird.quelle
Deshalb brauchen wir
ensure
:quelle
Ja,
ensure
wiefinally
garantiert, dass der Block ausgeführt wird . Dies ist sehr nützlich, um sicherzustellen, dass kritische Ressourcen geschützt sind, z. B. das Schließen eines Dateihandles bei Fehlern oder das Freigeben eines Mutex.quelle
File.open
Teil NICHT im Start-Sicherstellungsblock befindet. Nurfile.close
ist, aber es ist nicht genug.