Chyby a pcall

Zatím chyby hlásila sama Lua: volání nil, sčítání s nil… Chyby ale můžou hlásit i vaše funkce. Když funkce dostane hodnoty, se kterými neumí pracovat, je lepší skončit se srozumitelnou hláškou než pokračovat se špatným výsledkem. K tomu slouží error:

local mince = 20

local function kupSemena(cena, balicky)
    local naklady = cena * balicky
    if naklady > mince then
        error("Málo mincí")
    end
    mince = mince - naklady
    return mince
end

print(kupSemena(2, 5))
print(kupSemena(5, 4))
print("Hotovo")

Vypíše:

10
main.lua:6: Málo mincí
stack traceback:
	[C]: in function 'error'
	main.lua:6: in local 'kupSemena'
	main.lua:13: in main chunk

error program zastaví, stejně jako chyba, kterou hlásí Lua: Hotovo se už nevypíše. Lua před vaši hlášku přidá main.lua:6:, řádek, na kterém se error zavolal. Traceback ukazuje, jak se tam program dostal. Čtěte ho odspodu: hlavní program na řádku 13 zavolal kupSemena a ta na řádku 6 zavolala error. ([C] znamená funkci zabudovanou do Lua, která je napsaná v jazyce C.) Když pozici ve zprávě nechcete, předejte jako druhý argument 0: error("Málo mincí", 0).

„Když tohle neplatí, skonči chybou“ je tak častá kontrola, že pro ni existuje zkratka: assert(podminka, hlaska). Když podmínka platí, assert nic nedělá. Když je false nebo nil, skončí s danou hláškou:

local function zasej(plodina, zahony)
    assert(zahony > 0, "Zasejte aspoň jeden záhon")
    print("Zaseto: " .. plodina .. ", záhonů: " .. zahony)
end

zasej("mrkev", 3)
zasej("pšenice", 0)

Vypíše:

Zaseto: mrkev, záhonů: 3
main.lua:2: Zasejte aspoň jeden záhon

Někdy by ale chyba neměla ukončit celý program. Ema si nemůže dovolit semena dýně, ale ostatní semena koupit chce. pcall (protected call, chráněné volání) zavolá funkci a zachytí její chybu. Předejte mu funkci a za ní její argumenty: pcall(kupSemena, 5, 4) zavolá kupSemena(5, 4). pcall vrátí několik hodnot: když všechno proběhne dobře, true a to, co vrátila funkce; při chybě false a chybovou hlášku. V obou případech program pokračuje:

local mince = 20

local function kupSemena(cena, balicky)
    local naklady = cena * balicky
    if naklady > mince then
        error("Málo mincí")
    end
    mince = mince - naklady
    return mince
end

print(pcall(kupSemena, 2, 5))
local ok, vysledek = pcall(kupSemena, 5, 4)
if ok then
    print("Zbývá mincí: " .. vysledek)
else
    print("Chyba: " .. vysledek)
end
print("Hotovo")

Vypíše:

true	10
Chyba: main.lua:6: Málo mincí
Hotovo

Obvyklý je druhý způsob: hodnoty uložit do ok a vysledek a podle ok rozhodnout, co vysledek je. Typická chyba je napsat pcall(kupSemena(5, 4)). Se závorkami za kupSemena Lua funkci zavolá hned, ještě před pcall, a její chyba se nezachytí. Stejně jako u každé funkce, kterou předáváte jiné funkci, předejte samotnou funkci a její argumenty zvlášť.

Pokyny

Eminy mince klesnou pod nulu. Ve funkci kupSemena před placením skončete pomocí error("Málo mincí na " .. plodina, 0), když je naklady větší než mince. Druhý nákup by pak zastavil celý program, a tak všechny tři nákupy zavolejte přes pcall a vypište, co vrátí, například print(pcall(kupSemena, "mrkev", 2, 5)). Program vypíše:

true	10
false	Málo mincí na dýně
true	6

Nula balíčků se koupit nedá. Na začátek funkce kupSemena přidejte assert s podmínkou balicky > 0 a hláškou "Kupte aspoň jeden balíček". Pak na konci programu vypište pcall(kupSemena, "kukuřice", 3, 0). Nový řádek obsahuje false a hlášku s pozicí, například:

false	main.lua:5: Kupte aspoň jeden balíček

Napište funkci zkusKoupit s parametry plodina, cena a balicky. Zavolá kupSemena přes pcall a výsledky uloží do ok a vysledek. Když se nákup povede, vypíše Koupeno: …, zbývá mincí: …, jinak vypíše Nelze koupit …: a chybovou hlášku. Na konci programu zavolejte zkusKoupit("jahody", 4, 1) a zkusKoupit("brambory", 3, 2). Program končí takto:

Koupeno: jahody, zbývá mincí: 2
Nelze koupit brambory: Málo mincí na brambory

Začněte programovat zdarma

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

10/11