English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby 异常

Fehler und Ausführung werden immer miteinander verbunden. Wenn Sie eine nicht vorhandene Datei öffnen und dies nicht angemessen behandeln, dann wird Ihr Programm als minderwertig angesehen.

Wenn ein Fehler auftritt, wird das Programm gestoppt. Fehler werden verwendet, um verschiedene Arten von Fehlern zu behandeln, die während der Ausführung des Programms auftreten können, daher müssen angemessene Maßnahmen ergriffen werden, um sicherzustellen, dass das Programm nicht vollständig angehalten wird.

Ruby bietet ein perfektes Mechanismus zur Fehlerbehandlung. Wir können begin/end Der Block enthält möglicherweise auftretende Fehlercodes und verwendet rescue Der Unterausschnitt teilt Ruby mit, welche Arten von Ausnahmen perfekt behandelt werden sollen.

Syntax

begin # beginnt
 
 raise.. # wirft einen Fehler aus
 
rescue [ExceptionType = StandardException] # fängt den angegebenen Fehler-Typ ab, Standardwert ist StandardException
 $! # zeigt die Fehlerinformation
 $@ # zeigt den Code-Position, an dem der Fehler aufgetreten ist
else # andere Ausnahmen
 ..
ensure # Egal ob es eine Ausnahme gibt oder nicht, der Codeblock wird betreten
 
end # Ende

zu begin von rescue zu rescue alles ist geschützt. Wenn während der Ausführung des Codeblocks eine Ausnahme auftritt, wird der Kontrollfluss an end und

zwischen begin Jeder rescue Klauseln, Ruby vergleicht die ausgelöste Ausnahme mit jedem Parameter abwechselnd. Wenn der in der rescue-Klausel genannte Ausnahme Typ mit der aktuellen ausgelösten Ausnahme Typ übereinstimmt oder eine Überklasse ist, dann ist eine Übereinstimmung erfolgreich.

Wenn die Ausnahme nicht mit allen angegebenen Fehlerarten übereinstimmt, können wir in allen rescue Klausel verwendet einen else Klausel.

在线示例

#!/usr/bin/ruby
 
begin
   file = open("/unexistant_file)
   if file
      puts "Datei erfolgreich geöffnet"
   end
rescue
      file = STDIN
end
print file, "==", STDIN, "\n"

Die folgenden Beispiel-Ausgabeergebnisse. Sie können sehen,STDIN ersetzt file , weilÖffnenfehlgeschlagen.

#<IO:0xb7d16f84>==#<IO:0xb7d16f84>

verwendet retry Anweisung

Sie können rescue Block erfasst die Ausnahme und verwendet retry Der Statement wird von Anfang an ausgeführt begin Block.

Syntax

begin
    # Die von diesem Codeblock ausgeworfenen Ausnahmen werden von der folgenden rescue-Klausel erfasst
rescue
    # Dieser Block fängt alle Arten von Ausnahmen
    retry # Dies wird den Kontrollfluss zum Anfang von begin zurücksetzen
end

在线示例

#!/usr/bin/ruby
 
begin
   file = open("/unexistant_file)
   if file
      puts "Datei erfolgreich geöffnet"
   end
rescue
   fname = "existant_file"
   retry
end

Hier ist der Verarbeitungsablauf:

  • Es trat eine Ausnahme beim Öffnen auf.

  • Springen Sie zu rescue. fname wird neu zugewiesen.

  • Springen Sie durch retry zum Anfang von begin.

  • Diesmal wurde die Datei erfolgreich geöffnet.

  • Fahren Sie mit dem grundlegenden Prozess fort.

Hinweis:Wenn die umbenannte Datei nicht existiert, versucht der Beispielcode endlos. Daher verwenden Sie vorsichtig die Ausnahmebehandlung. retry.

verwendet raise Anweisung

Sie können raise Das Statement wirft eine Ausnahme. Der folgende Methodenaufruf wirft eine Ausnahme. Seine zweite Nachricht wird ausgegeben.

Syntax

raise 
 
oder
 
raise "Error Message" 
 
oder
 
raise ExceptionType, "Error Message"
 
oder
 
raise ExceptionType, "Error Message" condition

Die erste Form wirft die aktuelle Ausnahme einfach weiter (wenn keine aktuelle Ausnahme vorhanden ist, wird ein RuntimeError geworfen). Dies wird in Exception-Handler verwendet, die vor dem Übergeben der Ausnahme die Ausnahme erklären müssen.

Die zweite Form erstellt eine neue RuntimeError Ausnahme, die Nachricht auf die angegebene Zeichenkette setzt. Diese Ausnahme wird nachfolgend in den Aufrufstapel geworfen.

Die dritte Form verwendet den ersten Parameter, um eine Ausnahme zu erstellen und die zugehörige Nachricht auf den zweiten Parameter zu setzen.

Die vierte Form ähnelt der dritten Form, Sie können zusätzliche Bedingungsanweisungen (z.B. unless), um eine Ausnahme auszulösen.

在线示例

#!/usr/bin/ruby
 
begin  
    puts 'Ich bin vor dem raise.'  
    raise 'Ein Fehler ist aufgetreten.'  
    puts 'Ich bin nach dem raise.'  
rescue  
    puts 'Ich werde gerettet.'  
end  
puts 'Ich bin nach dem begin-Block.'

Der Ausgabebildschirm des obigen Beispiels zeigt:

Ich bin vor dem raise.  
Ich werde gerettet.  
Ich bin nach dem begin-Block.

eine andere Demonstration raise Beispiel zur Verwendung:

在线示例

#!/usr/bin/ruby
 
begin  
  raise 'A test exception.'  
rescue Exception => e  
  puts e.message  
  puts e.backtrace.inspect  
end

Der Ausgabebildschirm des obigen Beispiels zeigt:

A test exception.
["main.rb:4"]

verwendet ensure Anweisung

Manchmal müssen Sie sicherstellen, dass bestimmte Verarbeitungen am Ende des Codeblocks abgeschlossen werden, wenn eine Ausnahme geworfen wird. Zum Beispiel können Sie möglicherweise eine Datei beim Eintreten öffnen, und wenn Sie den Block verlassen, müssen Sie sicherstellen, dass die Datei geschlossen wird.

ensure Der Satz macht dies. ensure wird nach dem letzten rescue-Satz platziert und enthält einen Codeblock, der immer ausgeführt wird, wenn der Block beendet wird. Es spielt keine Rolle, ob der Block normal beendet wird, ob eine Ausnahme geworfen und behandelt wird oder ob der Block aufgrund einer nicht erfassten Ausnahme abgebrochen wird,ensure Der Block wird immer ausgeführt.

Syntax

begin 
   #.. Prozess
   #.. Ausnahme werfen
rescue 
   #.. Fehlerbehandlung 
ensure 
   #.. Stellen Sie sicher, dass die Ausführung am Ende erfolgt
   #.. Dies wird immer ausgeführt
end

在线示例

begin
  raise 'A test exception.'
rescue Exception => e
  puts e.message
  puts e.backtrace.inspect
ensure
  puts "Sicherstellung der Ausführung"
end

Der Ausgabebildschirm des obigen Beispiels zeigt:

A test exception.
["main.rb:4"]
Sicherstellung der Ausführung

verwendet else Anweisung

wenn bereitgestellt else Satz, der normalerweise in rescue Nach dem Satz, irgendein ensure davor.

else Der Körper des Satzes wird nur ausgeführt, wenn der Körper des Codes keine Ausnahme wirft.

Syntax

begin 
   #.. Prozess 
   #.. Ausnahme werfen
rescue 
   #.. Fehlerbehandlung
else
   #.. Führen Sie aus, wenn keine Ausnahme auftritt
ensure 
   #.. Stellen Sie sicher, dass die Ausführung am Ende erfolgt
   #.. Dies wird immer ausgeführt
end

在线示例

begin
 # Auswerfen einer 'A test exception.'
 puts "Ich erhebe keine Ausnahme"
rescue Exception => e
  puts e.message
  puts e.backtrace.inspect
else
   puts "Herzlichen Glückwunsch"-- keine Fehler!"
ensure
  puts "Sicherstellung der Ausführung"
end

Der Ausgabebildschirm des obigen Beispiels zeigt:

Ich erhebe keine Ausnahme
Herzlichen Glückwunsch-- keine Fehler!
Sicherstellung der Ausführung

Mit dem Variablen $! kann die von einer Ausnahme ausgestoßene Fehlermeldung erfasst werden.

Catch und Throw

Das Mechanismus von raise und rescue kann den Ausführung abbrechen, wenn ein Fehler auftritt, manchmal ist es notwendig, einige tiefere Strukturen während der normalen Verarbeitung zu verlassen. In solchen Fällen sind catch und throw von Vorteil.

catch Definiert einen Block, der mit dem gegebenen Namen (der ein Symbol oder String sein kann) als Marke verwendet wird. Der Block wird normal ausgeführt, bis ein throw auftritt.

Syntax

throw :lablename
#.. Dies wird nicht ausgeführt.
catch :lablename do
#.. Nach dem Auftreten eines throw wird der catch ausgeführt.
end
 
oder
 
throw :lablename condition
#.. Dies wird nicht ausgeführt.
catch :lablename do
#.. Nach dem Auftreten eines throw wird der catch ausgeführt.
end

在线示例

Im folgenden Beispiel wird eine throw verwendet, um die Interaktion mit dem Benutzer zu beenden, wenn der Benutzer auf jede Aufforderung mit '!'-Antwort gibt.

在线示例

def promptAndGet(prompt)
   print prompt
   res = readline.chomp
   throw :quitRequested if res == "!"
   return res
end
 
catch :quitRequested do
   name = promptAndGet("Name: ")
   age = promptAndGet("Age: ")
   sex = promptAndGet("Sex: ")
   # ..
   # Behandlung der Informationen
end
promptAndGet("Name:")

Das obige Programm erfordert eine manuelle Interaktion, Sie können es auf Ihrem Computer ausprobieren. Der Ausgabefehler des obigen Beispiels ist:

Name: Ruby on Rails
Age: 3
Sex: !
Name:Just Ruby

Klasse Exception

Ruby-Standardklassen und -Module werfen Ausnahmen. Alle Ausnahme-Klassen bilden eine Hierarchie, einschließlich der Klasse Exception an der Spitze. Die nächste Ebene besteht aus sieben verschiedenen Typen:

  • Interrupt

  • NoMemoryError

  • SignalException

  • ScriptError

  • StandardError

  • SystemExit

Fatal ist eine weitere Ausnahme in dieser Ebene, aber der Ruby-Interpreter verwendet sie nur intern.

ScriptError und StandardError haben einige Unterklassen, aber wir müssen uns hier nicht mit diesen Details beschäftigen. Das Wichtigste ist, unsere eigenen Ausnahme-Klassen zu erstellen, die Klassen Exception oder deren Nachkommen sein müssen.

让我们看一个示例:

在线示例

class FileSaveError < StandardError
   attr_reader :reason
   def initialize(reason)
      @reason = reason
   end
end

现在,看下面的示例,将使用上面的异常:

在线示例

File.open(path, "w") do |file|
begin
    # 写出数据 ...
rescue
    # 发生错误
    raise FileSaveError.new($!)
end
end

在此,最重要的一行是 raise FileSaveError.new($!)。我们使用 raise 来表示异常已发生,将其传递给 FileSaveError 的新示例,由于特定的异常导致数据写入失败。