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

Usunięta treść Dodana treść
Szymon wro (dyskusja | edycje)
Nie podano opisu zmian
Szymon wro (dyskusja | edycje)
Nie podano opisu zmian
Linia 1:
== Przetwarzanie wyjątków: rescue ==
 
Wykonujący się program może napotkać na niespodziewane problemy. Plik, które chce odczytać może nie istnieć, dysk może być pełny, gdy program chcetrzeba zapisać trochę danychdane, a użytkownik może wprowadzaćwprowadza niepoprawny rodzaj danych wejściowych.
 
<pre>
ruby> file = open("some_filejakis_plik")
ERR: (eval):1:in `open': No such file or directory - some_filejakis_plik
</pre>
 
Solidny program powinien radzić sobie z takimi sytuacjami sensownie i wdzięcznie. Sprostanie temu wymaganiu może być irytującym zadaniem. Od programistów języka C oczekuje się sprawdzania wyniku każdego wywołania systemowego które potencjalnie mogło się nie powieść oraz natychmiastowego zdecydowaniezdecydowania, co należy zrobić:
 
<pre>
FILE *fileplik = fopen("some_filejakis_plik", "r");
if (fileplik == NULL) {
fprintf( stderr, "FilePlik doesn'tnie exististnieje.\n" );
exit(1);
}
bytes_readbajty_przeczytane = fread( buf, 1, bytes_desiredbajty_zadane, file );
if (bytes_readbajty_przeczytane != bytes_desired bajty_zadane) {
/* dotutaj morewiecej errorkodu handling hereobslugi bledow... */
}
...
</pre>
 
Jest to bardzo męcząca praktyka, którą programiści mają w zwyczaju traktować niedbale i pomijać, czego rezultatem jest to, że program nie radziźle sobie dobrzeradzi z wyjątkami. Z drugiej strony, dobreporządne wykonanie tej pracy czyni programy trudnymi do czytania, ponieważ duża ilość kodu obsługującegoobsługi wyjątkiwyjątków przesłania właściwywłaściwą logikę kodprogramu.
 
W Rubim, tak jak w wielu współczesnych językach programowania, możemy radzić sobie z wyjątkami poszczególnych bloków kodu rozdzielnieoddzielnie, leczco w taka praca z niespodziankamijednak skutecznie acz nie nadmiernie obciąża programistę lub każdego, kto później będzie potem czytał kod. Blok kodu oznaczony oznaczony słowem <tt>begin</tt> wykonuje się dopóki nie napotka na wyjątek, które powoduje przekierowanie kontroli do bloku zarządzania błędami, który jest oznaczony przez <tt>rescue</tt>. Jeżeli nie wystąpi żaden wyjątek, kod z bloku <tt>rescue</tt> nie jest używany. Następująca metoda zwraca pierwszą linię z pliku tekstowego lub <tt>nil</tt> jeżeli napotka wyjątek:
 
<pre>
def pierwsza_linia(nazwa_pliku)
def first_line( filename )
begin
fileplik = open("some_file"nazwa_pliku)
info = file.gets
fileplik.close
info # Ostatnia obliczona rzecz jest zwracaną wartościązwracana
rescue
nil # Nie możeszmozesz przeczytaćprzeczytac pliku? więc nie zwracaj łańcuchałancucha
end
end
</pre>
 
Będą występować sytuacje, gdy będziemy chcieli móc kreatywnie pracować nad problemem. Tutaj, jeśli plik, który żądamy jest niedostępny, możemy spróbować użyć standardowego wejścia:
 
<pre>
begin
fileplik = open("some_filejakis_plik")
rescue
fileplik = STDIN
end
 
begin
# ... processprzetwarzaj the inputwejscie ...
rescue
# ... andtutaj dealobsluguj with any other exceptions herewyjatki.
end
</pre>
Linia 59:
 
<pre>
fnamenazwap = "some_filejakis_plik"
begin
fileplik = open(fnamenazwap)
# ... processprzetwarzaj the inputwejscie ...
rescue
fnamenazwap = "STDIN"
retry
end
Linia 71:
Jednakże, mamy tutaj pewną wadę. Nieistniejący plik sprawi, że pętla ta będzie powtarzana w nieskończoność. Musisz zwracać uwagę na tego rodzaju pułapki podczas przetwarzania wyjątków.
 
Każda biblioteka Rubiego podnosi wyjątek jeśli wystąpi jakiś błąd. Ty również możesz podnosić wyjątki jawnie w twoim kodzie. By podnieść wyjątek użyj słowa kluczowego <tt>raise</tt>. Przyjmuje ono jeden argument, którym powinien być łańcuch znakowy opisujący wyjątek. Argument jest wprawdzie opcjonalny, jednak nie powinien być pomijany. Będzie on mógł być później dostępny za pomocą specjalnej zmiennej globalnej <tt>$!</tt>.
 
<pre>
ruby> raise "testblad errortestowy"
testblad errortestowy
ruby> begin
| raise "test2"
| rescue
| puts "AnWystapil error occurredblad: #{$!}"
| end
AnWystapil error occurredblad: test2
nil
</pre>
 
<noinclude>
{{ProstaNawigacja|spis=Ruby|poprzart=Ruby/Stałe klasowe|poprz=Stałe klasowe|nastart=Ruby/Przetwarzanie wyjątków: ensure|nast=Przetwarzanie wyjątków: ensure}}
</noinclude>