Ruby/Przetwarzanie wyjątków: ensure
Z Wikibooks, biblioteki wolnych podręczników.
[edytuj] Przetwarzanie wyjątków: ensure
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.