Ich habe einen Code, der mehrere Arten von Ausnahmen in Ruby retten muss:
begin
a = rand
if a > 0.5
raise FooException
else
raise BarException
end
rescue FooException, BarException
puts "rescued!"
end
Ich möchte irgendwie die Liste der Ausnahmetypen speichern, die ich irgendwo retten möchte, und diese Typen an die Rettungsklausel übergeben:
EXCEPTIONS = [FooException, BarException]
und dann:
rescue EXCEPTIONS
Ist das überhaupt möglich und ist es möglich ohne einige wirklich hackige Anrufe eval
? Ich bin nicht hoffnungsvoll, da ich sehe, TypeError: class or module required for rescue clause
wenn ich das oben genannte versuche.
Antworten:
Sie können ein Array mit dem Splat-Operator verwenden
*
.Wenn Sie eine Konstante für das Array wie oben (mit
EXCEPTIONS
) verwenden möchten, beachten Sie, dass Sie sie nicht innerhalb einer Definition definieren können. Wenn Sie sie auch in einer anderen Klasse definieren, müssen Sie mit ihrem Namespace darauf verweisen. Eigentlich muss es keine Konstante sein.Splat-Operator
Der Splat-Operator
*
"entpackt" ein Array an seiner Position, so dassbedeutet das gleiche wie
Sie können es auch in einem Array-Literal als verwenden
das ist das gleiche wie
oder in einer Argumentationsposition
was bedeutet
[]
erweitert sich auf Leerstand:Ein Unterschied zwischen Rubin 1.8 und Rubin 1.9 besteht bei
nil
.Seien Sie vorsichtig mit Objekten, auf die
to_a
definiert ist, wieto_a
in solchen Fällen angewendet wird:Bei anderen Objekttypen gibt es sich selbst zurück.
quelle
EXCEPTIONS
in diesem Fall der Begriff für die Verwendung des Zeichens '*' vor ? Möchte ein bisschen mehr lernen.rescue InvalidRequestError, CardError => e
(siehe mikeferrier.com/2012/05/19/… )rescue *EXCEPTIONS => e
, wobeiEXCEPTIONS
sich ein Array von Ausnahmeklassennamen befindet.Obwohl die Antwort von @sawa technisch richtig ist, denke ich, dass sie Rubys Ausnahmebehandlungsmechanismus missbraucht.
Wie der Kommentar von Peter Ehrlich nahe legt (indem er auf einen alten Blog-Beitrag von Mike Ferrier verweist ), ist Ruby bereits mit einem DRY-Ausnahmebehandlungsmechanismus ausgestattet:
Mit dieser Technik können wir auf das Ausnahmeobjekt zugreifen, das normalerweise einige wertvolle Informationen enthält.
quelle
Ich bin gerade auf dieses Problem gestoßen und habe eine alternative Lösung gefunden. In dem Fall, dass Ihre
FooException
undBarException
alle benutzerdefinierte Ausnahmeklassen sind und insbesondere wenn sie alle thematisch miteinander verbunden sind, können Sie Ihre Vererbungshierarchie so strukturieren, dass sie alle von derselben übergeordneten Klasse erben und dann nur die übergeordnete Klasse retten.Zum Beispiel hatte ich drei Ausnahmen:
FileNamesMissingError
,,InputFileMissingError
undOutputDirectoryError
das wollte ich mit einer Aussage retten. Ich habe eine andere Ausnahmeklasse namens aufgerufenFileLoadError
und dann die obigen drei Ausnahmen eingerichtet, um davon zu erben. Ich habe dann nur gerettetFileLoadError
.So was:
quelle