Chyby v korutinách
Co se stane, když se uvnitř korutiny něco pokazí? Druhý den má Hugo na své trase potíže:
-- Hugo ztratil mapu
local hugo = coroutine.create(function()
coroutine.yield("trh")
error("Hugo ztratil mapu")
coroutine.yield("farma")
end)
print(coroutine.resume(hugo))
print(coroutine.resume(hugo))
print(coroutine.status(hugo))
print(coroutine.resume(hugo))
print("Den pokračuje.")Vypíše:
true trh
false main.lua:4: Hugo ztratil mapu
dead
false cannot resume dead coroutine
Den pokračuje.Chyba uvnitř korutiny nezastaví program, jen korutinu. Ta je od té chvíle dead (na farmu už se nedostane) a resume vrátí false a chybovou hlášku, přesně jako pcall. Ani spuštění mrtvé korutiny není chyba: dostanete false a cannot resume dead coroutine („nelze pokračovat v mrtvé korutině“).
To se hodí, protože jedna rozbitá postava nezastaví celou hru. Je to ale i past: když se nepodíváte, co resume vrátilo, chyba zmizí beze stopy a korutina prostě potichu přestane cokoli dělat. Když se tedy v korutině něco nestane, vypište si, co vrací resume. V hotovém programu kontrolujte první hodnotu: po local ok, hlaska = coroutine.resume(hugo) je ok rovno false, když se něco pokazilo, a hlaska říká co.
Generátor je jiný. Funkce z coroutine.wrap nevrací true ani false, a proto chybu pošle dál a program skončí jako u každé jiné chyby:
-- Hugo zase ztratil mapu
local dalsiZastavka = coroutine.wrap(function()
coroutine.yield("trh")
error("Hugo ztratil mapu")
end)
print(dalsiZastavka())
print(dalsiZastavka())
print("Tenhle řádek se nikdy nespustí.")Vypíše:
trh
main.lua:8: main.lua:4: Hugo ztratil mapuHláška má dvě čísla řádků: main.lua:8: je místo, kde byl generátor zavolán, a main.lua:4: místo, kde uvnitř něj chyba nastala. Spotřebovaný generátor zastaví program stejně, chybou cannot resume dead coroutine. Pokud potřebujete chybu z generátoru zachytit, zavolejte ho pomocí pcall, jako každou jinou funkci: local ok, zastavka = pcall(dalsiZastavka).
Ještě jednu chybu už z této lekce znáte: coroutine.yield() mimo korutinu, třeba ve funkci, kterou jste zavolali přímo, skončí hláškou attempt to yield from outside a coroutine.
Jak psát:
Pokyny
Hugo si každý den koupí dýni za 20 mincí. Spusťte program: 3. a 4. den vypíše nesmysl, protože v mince je v tyto dny chybová hláška, a ne číslo. (error(…, 0) vynechá číslo řádku, jak víte z lekce o funkcích.) Kontrolujte ok: když je false, vypište místo toho den a hlášku, třeba Den 3: Hugovi zbylo jen 10 mincí. Program vypíše:
Den 1: Hugo má 30 mincí
Den 2: Hugo má 10 mincí
Den 3: Hugovi zbylo jen 10 mincí
Den 4: cannot resume dead coroutineSpouštět mrtvou korutinu nemá smysl. Na začátku každého dne zkontrolujte Hugův stav: když je dead, vypište místo spuštění den a Hugo odešel domů. Program vypíše:
Den 1: Hugo má 30 mincí
Den 2: Hugo má 10 mincí
Den 3: Hugovi zbylo jen 10 mincí
Den 4: Hugo odešel domů.Začněte programovat zdarma
5/6