Ruby/Przetwarzanie wyjątków: ensure
Przetwarzanie wyjątków: ensure
[edytuj]Może się tak zdarzyć, że potrzebne jest dodatkowe sprzątanie, gdy metoda kończy swoją pracę. Być może otwarty plik powinien być zamknięty, bufor opróżniony, itp. Jeżeli byłby zawsze tylko jeden punkt wyjścia dla każdej metody, moglibyśmy z pełną ufnością umieścić kod czyszczący w jednym miejscu i wiedzielibyśmy, że zostanie on wykonany. Jednakże, metoda może zwracać wartość z różnych miejsc, lub nasze zamierzone czyszczenie może być niespodziewane ominięte z powodu wyjątku.
begin
plik = open("/tmp/jakis_plik", "w")
# ... zapis do pliku ...
plik.close
end
W powyższym przykładzie, jeżeli wyjątek wystąpiłby w sekcji kodu, w której dokonujemy zapisu do pliku, plik mógłby pozostać otwarty. A my nie chcemy uciekać się tego rodzaju redundancji:
begin
plik = open("/tmp/jakis_plik", "w")
# ... zapis do pliku ...
plik.close
rescue
plik.close
fail # ponownie podnosi przechwycony wyjatek
end
Ten kod nie dość, że niezdarny, będzie jeszcze bardziej skomplikowany, ponieważ trzeba będzie obsługiwać każdy return i break.
Z tego powodu dodamy nowe słowo kluczowe do naszego schematu "begin...rescue...end", którym jest ensure. Blok ensure wykonuje się niezależnie od pomyślnego lub niepomyślnego zakończenia bloku begin.
begin
plik = open("/tmp/jakis_plik", "w")
# ... zapis do pliku ...
rescue
# ... obsluga wyjatkow ...
ensure
plik.close # ... zawsze wykonywane.
end
Możliwe jest używanie ensure bez rescue i vice versa, ale jeśli używane są razem w tym samym bloku begin...end, rescue musi poprzedzać ensure.