Jaka jest różnica - techniczny, filozoficzne, koncepcyjnego, albo inaczej - międzyJaka jest różnica między `raise" foo "` i `raise Exception.new (" foo ")`?
raise "foo"
i
raise Exception.new("foo")
?
Jaka jest różnica - techniczny, filozoficzne, koncepcyjnego, albo inaczej - międzyJaka jest różnica między `raise" foo "` i `raise Exception.new (" foo ")`?
raise "foo"
i
raise Exception.new("foo")
?
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 raise
dowolny typ obiektu, puste rescue
wola domyślnie tylko złapać czegokolwiek, która dziedziczy StandardError
.Cała reszta musi być konkretna.
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
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, 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
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? –