Výjimky 2
Obraz který jsme si o výjimkách udělali z předchozího dílu je velmi užitečný protože vám dovolí řídit výjimky mnohem lépe. Pokud potřebujete zavolat specifickou výjimku můžete použít některou z již předdeklarovaných výjimek nebo si definujete jednu vaši vlastní.
Jak definovat vlastní výjimku?
class FileLoadError < StandardError
attr_reader :proc
def initialize(proc)
@proc = proc
end
end
Obecně se doporučuje udělat výjimku jako podtřídu StandardError nebo jednoho z potomků k tomu, aby bylo zajištěno, že bude chycená standardně.
BEGIN - END práce s výjimkou
Pod termínem "práce s" si můžete představit jak má nebo "co" by měl program dělat v případě pokud se stane jistá chyba. Dívejte se na obsah mezi BEGIN a END jako kdyby byl sdělením k "případu"...Ruby už samo vybírá kterou výjimku má zpracovat. Raise a Rescue v podstatě způsobí přerušení exekuce.
begin
.... <- info co má být testováno,zpracováno
rescue LoadError, NameError => promenna_k_danne_vyjimce
print "Problem pri nahravani souboru " + promenna_k_danne_vyjimce
rescue SignalException => promenna_k_danne_vyjimce2
print "Prerusuji konflikt " + promenna_k_danne_vyjimce
else ....(Něco co se stane pokdu nejsou žádné výjimky)
ensure .... (stejné jako else, provádí se vždy)
(Pokud třeba pracujete se soubbory můžete si tak ověřit zda byly správně zavřeny)
end
Rescue s žádnými parametry vede ke StandardError
V případě, že vyzvednutá výjimka odpovídá parametru,Ruby vykoná odpovídající záchranné instrukce a zastaví další hledání.Porovnání je uděláno pomocí syntaxe parametr===$!
Ruby bude hledat nahoru jak naložit s chybou ve volající metodě, pak v metodě volající volanou metodu a tak dále jestli výjimka je vyvolaná vně begin/end bloku nebo jestli nejsou definované žádné rescue pravidla. Pokud není nalezeno žádné pravidlo jak zacházet s výjimkou, dokonce ani v nejvyšší úrovni, donutí to program k tomu aby se ukončil.
dailyentry = createentry()
whereto = createtodaypage()
begin
.... -> Tady začneme teprve zapisovat data do souboru, jinde ne.
rescue IOError
$stderr.puts “Chyba v zápisu dat. $!.”
waitminutes()
retry
end
Představte si, že chcete napsat skript k tomu, aby posílal položky bloku na vaši Ruby stránku.Část kódu nad může sloužit jako takový přinejmenším účelný koncept, kterým "vytvoříte" nový vstup bloku ve vyplněných jménech po dnešním datu, začnete psát, tisknete ENTER a bác!, vyskočí na vás chyba protože hdd na serveru je plný, nebo protože je fyzická chyba na sektoru, do kterého zkoušíte psát...a existuje spousta dalších důvodů.
Instruujete váš program pomocí "waitminutes" a potom obnovíte proces s pošlete váš vstup znovu.
Metody Catch a throw
Catch specifikuje blok označený jménem, které si vyberete (které může být řetězec nebo symbol).Blok kódu je vykonaný dokud se nesetká s "throw" instrukcí. Catch a throw je užívaný při syntaktické analýze skrz komplexní kód nebo strukturu dat a z nějakého důvodu pokud se setká s chybou, procházení dalšího kódu již není nezbytné.
Výtažek z kódu:
def prompt_and_get(prompt)
print prompt
res = readline.chomp
throw :quit_requested if res == "!"
res
end
catch :quit_requested do
name = prompt_and_get("Jmeno: ")
age = prompt_and_get("Věk: ")
sex = prompt_and_get("Pohlavi: ")
# ..
# informace procesu
end