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

Usunięta treść Dodana treść
Kj (dyskusja | edycje)
m nav
Szymon wro (dyskusja | edycje)
Nie podano opisu zmian
Linia 1:
== Przetwarzanie wyjątków: rescue ==
An executing program can run into unexpected problems. A file that it wants to read might not exist; the disk might be full when it wants to save some data; the user may provide it with some unsuitable kind of input.
 
Wykonujący się program może napotkać niespodziewane problemy. Plik, które chce odczytać może nie istnieć, dysk może być pełny, gdy program chce zapisać trochę danych, a użytkownik może wprowadzać niepoprawny rodzaj danych wejściowych.
 
<pre>
ruby> file = open("some_file")
ERR: (eval):1:in `open': No such file or directory - some_file
</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 zdecydowanie, co należy zrobić:
A robust program will handle these situations sensibly and gracefully. Meeting that expectation can be an exasperating task. C programmers are expected to check the result of every system call that could possibly fail, and immediately decide what is to be done:
 
<pre>
FILE *file = fopen("some_file", "r");
if (file == NULL) {
Linia 16 ⟶ 21:
}
...
</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 sobie dobrze z wyjątkami. Z drugiej strony, dobre wykonanie tej pracy czyni programy trudnymi do czytania, ponieważ duża ilość kodu obsługującego wyjątki przesłania właściwy kod.
This is such a tiresome practice that programmers can tend to grow careless and neglect it, and the result is a program that doesn't handle exceptions well. On the other hand, doing the job right can make programs hard to read, because there is so much error handling cluttering up the meaningful code.
 
W Rubim, tak jak w wielu współczesnych językach programowania, możemy radzić sobie z wyjątkami poszczególnych bloków kodu rozdzielnie, lecz w taka praca z niespodziankami skutecznie acz nie nadmiernie obciąża programistę lub każdego, kto później będzie 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:
In ruby, as in many modern languages, we can handle exceptions for blocks of code in a compartmentalized way, thus dealing with surprises effectively but not unduly burdening either the programmer or anyone else trying to read the code later. The block of code marked with begin executes until there is an exception, which causes control to be transferred to a block of error handling code, which is marked with rescue. If no exception occurs, the rescue code is not used. The following method returns the first line of a text file, or nil if there is an exception:
 
<pre>
def first_line( filename )
begin
Linia 26 ⟶ 33:
info = file.gets
file.close
info # LastOstatnia thingobliczona evaluatedrzecz isjest thezwracaną return valuewartością
rescue
nil # Can'tNie readmożesz theprzeczytać filepliku? thenwięc don'tnie returnzwracaj a stringłańcucha
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:
There will be times when we would like to be able to creatively work around a problem. Here, if the file we want is unavailable, we try to use standard input instead:
 
<pre>
begin
file = open("some_file")
Linia 45 ⟶ 54:
# ... and deal with any other exceptions here.
end
</pre>
 
Słowo kluczowe <tt>retry</tt> może być używane w bloku <tt>rescue</tt>, by wystartować blok <tt>begin</tt> od początku. Pozwala to nam przepisać poprzedni przykład nieco zwięźlej:
retry can be used in the rescue code to start the begin code over again. It lets us rewrite the previous example a little more compactly:
 
<pre>
fname = "some_file"
begin
Linia 56 ⟶ 67:
retry
end
</pre>
 
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.
However, there is a flaw here. A nonexistent file will make this code retry in an infinite loop. You need to watch out for such pitfalls when using retry for exception processing.
 
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>.
Every ruby library raises an exception if any error occurs, and you can raise exceptions explicitly in your code too. To raise an exception, use raise. It takes one argument, which should be a string that describes the exception. The argument is optional but should not be omitted. It can be accessed later via the special global variable $!.
 
<pre>
ruby> raise "test error"
test error
Linia 70 ⟶ 83:
An error occurred: 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}}