Ruby/Przetwarzanie wyjątków: ensure: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Szymon wro (dyskusja | edycje)
Szymon wro (dyskusja | edycje)
Nie podano opisu zmian
Linia 3:
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.
 
<source lang="ruby">
<pre>
begin
plik = open("/tmp/jakis_plik", "w")
Linia 9:
plik.close
end
</presource>
 
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 [[w:Redundancja|redundancji]]:
 
<source lang="ruby">
<pre>
begin
plik = open("/tmp/jakis_plik", "w")
Linia 22:
fail # ponownie podnosi przechwycony wyjatek
end
</presource>
 
Ten kod nie dość, że niezdarny, będzie jeszcze bardziej skomplikowany, ponieważ trzeba będzie obsługiwać każdy <tt>return</tt> i <tt>break</tt>.
Linia 28:
Z tego powodu dodamy nowe słowo kluczowe do naszego schematu "<tt>begin...rescue...end</tt>", którym jest <tt>ensure</tt>. Blok <tt>ensure</tt> wykonuje się niezależnie od pomyślnego lub niepomyślnego zakończenia bloku <tt>begin</tt>.
 
<source lang="ruby">
<pre>
begin
plik = open("/tmp/jakis_plik", "w")
Linia 37:
plik.close # ... zawsze wykonywane.
end
</presource>
 
Możliwe jest używanie <tt>ensure</tt> bez <tt>rescue</tt> i vice versa, ale jeśli używane są razem w tym samym bloku <tt>begin...end</tt>, <tt>rescure</tt> musi poprzedzać <tt>ensure</tt>.