Mam kod, który musi uratować wiele typów wyjątków w Rubim:
begin
a = rand
if a > 0.5
raise FooException
else
raise BarException
end
rescue FooException, BarException
puts "rescued!"
end
Chciałbym w jakiś sposób zapisać listę typów wyjątków, które chcę gdzieś uratować i przekazać je do klauzuli ratunkowej:
EXCEPTIONS = [FooException, BarException]
i wtedy:
rescue EXCEPTIONS
Czy jest to w ogóle możliwe i czy jest to możliwe bez niektórych naprawdę hakerskich połączeń do eval
? Nie mam nadziei, biorąc pod uwagę, że widzę, TypeError: class or module required for rescue clause
kiedy próbuję wykonać powyższe.
Odpowiedzi:
Możesz użyć tablicy z operatorem splat
*
.Jeśli zamierzasz użyć stałej dla tablicy jak powyżej (z
EXCEPTIONS
), zwróć uwagę, że nie możesz jej zdefiniować w definicji, a także jeśli zdefiniujesz ją w innej klasie, musisz odwołać się do niej za pomocą jej przestrzeni nazw. Właściwie nie musi to być stała.Operator Splat
Operator splat
*
"rozpakowuje" tablicę w jej pozycji, tak żeoznacza to samo co
Można go również użyć w literale tablicowym jako
który jest taki sam jak
lub w pozycji argumentu
co znaczy
[]
rozszerza się do wakatu:Jedna różnica między ruby 1,8 a ruby 1,9 polega na
nil
.Uważaj na obiekty, na których
to_a
jest zdefiniowany, coto_a
zostanie zastosowane w takich przypadkach:W przypadku innych typów obiektów powraca.
źródło
EXCEPTIONS
tego przypadku? Chciałbym dowiedzieć się trochę więcej.rescue InvalidRequestError, CardError => e
(patrz mikeferrier.com/2012/05/19/... )rescue *EXCEPTIONS => e
gdzieEXCEPTIONS
jest tablicą nazw klas wyjątków.Podczas gdy odpowiedź udzielona przez @sawa jest technicznie poprawna, myślę, że niewłaściwie wykorzystuje mechanizm obsługi wyjątków Rubiego.
Jak sugeruje komentarz Petera Ehrlicha (wskazując na stary post na blogu Mike'a Ferriera ), Ruby jest już wyposażony w mechanizm obsługi wyjątków DRY:
Korzystając z tej techniki, możemy uzyskać dostęp do obiektu wyjątku, który zwykle zawiera cenne informacje.
źródło
Właśnie natknąłem się na ten problem i znalazłem alternatywne rozwiązanie. W przypadku Twojego
FooException
iBarException
gdy wszystkie będą niestandardowymi klasami wyjątków, a zwłaszcza jeśli wszystkie są powiązane tematycznie, możesz tak ustrukturyzować hierarchię dziedziczenia, aby wszystkie odziedziczyły z tej samej klasy nadrzędnej, a następnie uratują tylko klasę nadrzędną.Na przykład miałem trzy wyjątki:
FileNamesMissingError
,InputFileMissingError
, iOutputDirectoryError
że chciałem ratunek z jednego rachunku. Wywołałem inną klasę wyjątków,FileLoadError
a następnie ustawiłem powyższe trzy wyjątki, aby dziedziczyć po niej. Wtedy tylko uratowałemFileLoadError
.Lubię to:
źródło