2011-01-26 16 views

Odpowiedz

100

Technicznie pierwszy podnosi RuntimeError z komunikatem ustawiony "foo", a drugi podnosi wyjątek z komunikatem ustawiony "foo".

W praktyce istnieje znaczna różnica między tym, kiedy chcemy skorzystać z pierwszego i kiedy chcemy go użyć.

Po prostu, prawdopodobnie chcesz RuntimeError nie jest Exception. Blok ratunkowy bez argumentu złapie RuntimeErrors, ale NIE złapie Exception s. Więc jeśli zgłosi Exception w kodzie, to kod nie złapie go:

begin 
rescue 
end 

Aby złapać Exception trzeba będzie to zrobić:

begin 
rescue Exception 
end 

Oznacza to, że w pewnym sensie , Exception jest "gorszym" błędem niż RuntimeError, ponieważ musisz wykonać więcej pracy, aby go odzyskać.

To, czego chcesz, zależy od sposobu obsługi błędów przez projekt. Na przykład w naszych demonach główna pętla ma puste pole ratunkowe, które złapie RuntimeErrors, zgłoś je, a następnie kontynuuj. Ale w jednej lub dwóch okolicznościach chcemy, aby demon naprawdę umarł z powodu błędu, iw tym przypadku podnosimy Exception, który przechodzi przez nasz "normalny kod obsługi błędów" i na zewnątrz.

I znowu, jeśli piszesz kod biblioteki, to pewnie chcesz RuntimeError, a nie Exception, jak użytkownicy biblioteki będzie zaskoczony, jeśli podnosi błędy pusty rescue blok nie może złapać, a to zajmie im chwilę, by zrozumieć, dlaczego.

Wreszcie, należy powiedzieć, że RuntimeError jest podklasą klasy StandardError i rzeczywista zasada jest taka, że ​​chociaż można raisedowolny typ obiektu, puste rescue wola domyślnie tylko złapać czegokolwiek, która dziedziczy StandardError .Cała reszta musi być konkretna.

+1

bardzo pouczające, dzięki. kilka rzeczy: [1] Ten ostatni akapit był najbardziej pouczający i pozwól mi odkryć w irb coś, o czym nie wspomniałeś: 'RuntimeError

+1

[1, 2] Tak. [3] nie wiem ... [4] Kiedy koduję w moim najbardziej profesjonalnym, mam tendencję do tworzenia niestandardowych typów błędów, które dziedziczą po 'StandardError'. Nie musi być bardziej skomplikowana niż kilka linii, takich jak 'class MissingArgumentsError

+0

Bardzo pouczające, ale w jakich sytuacjach powinieneś rzucić wyjątek, a nie błąd czasu pracy, jeśli błąd czasu wykonywania jest preferowany do pisania libraray? –

26

From the offical documentation:

raise 
raise(string) 
raise(exception [, string [, array ] ]) 

Bez argumentów, podnosi wyjątek w $! lub podnosi RuntimeError jeśli $! jest zerowa. Z pojedynczym argumentem String, podnosi on RuntimeError z ciągiem jako wiadomością. W przeciwnym razie pierwszym parametrem powinna być nazwa klasy Exception (lub obiektu, który zwraca Exception przy wysyłaniu wyjątku). Opcjonalny drugi parametr ustawia komunikat związany z wyjątkiem, a trzeci parametr jest tablicą informacji zwrotnej. Wyjątki są objęte klauzulą ​​ratowania bloków begin...end.

raise "Failed to create socket" 
raise ArgumentError, "No parameters", caller 
Powiązane problemy