Funkce v tabulkách

V lekci o tabulkách jako slovnících jste jednu věc popsali jednou tabulkou, záznamem jako {nazev = "Mrkev", dny = 3}. V lekci o funkcích jste se naučili, že funkce je hodnota stejně jako číslo nebo text: můžete ji uložit do proměnné a předat jiné funkci. Když tyhle dvě věci spojíte, může tabulka hned vedle svých dat obsahovat i funkce:

local farma = {nazev = "Farma Slunečnice", mince = 120}

farma.popis = function(f)
    print(f.nazev .. ": " .. f.mince .. " mincí")
end

farma.popis(farma)

Vypíše:

Farma Slunečnice: 120 mincí

farma.popis = function(f) … end uloží funkci pod klíč popis, stejně jako farma.mince = 120 ukládá číslo pod klíč mince. V zápisu farma.popis(farma) vezme farma.popis funkci z tabulky a závorky ji zavolají. Funkce dostane farmu jako parametr f a čte z ní hodnoty.

Totéž jde v Lua zapsat kratčeji a tento zápis uvidíte mnohem častěji: function farma.popis(f) znamená přesně totéž co farma.popis = function(f). Na začátku není local, protože funkce se nestane novou proměnnou, ale uloží se do tabulky farma, která už existuje. Další příklad používá tenhle kratší zápis a ukazuje také, že funkce v tabulce může tabulku, kterou dostane, i měnit:

local farma = {nazev = "Farma Slunečnice", mince = 120}

function farma.popis(f)
    print(f.nazev .. ": " .. f.mince .. " mincí")
end

function farma.vydelej(f, castka)
    f.mince = f.mince + castka
end

farma.vydelej(farma, 30)
farma.popis(farma)

Vypíše:

Farma Slunečnice: 150 mincí

Proč funkci předávat farmu jako parametr, když by mohla rovnou použít farma? Protože pak funguje pro každou tabulku se stejnými klíči: farma.popis({nazev = "Farma dědy Josefa", mince = 80}) vypíše Farma dědy Josefa: 80 mincí. To se brzy bude hodit, až bude tabulek stejného druhu víc.

Tabulky s funkcemi používáte od začátku kurzu. string a math jsou obyčejné tabulky a string.upper je funkce uložená v tabulce string pod klíčem upper:

print(type(string), type(string.upper), type(math.floor))

Vypíše:

table	function	function

Tabulce, která drží data a zároveň funkce, které s těmi daty pracují, se říká objekt. O objektech je celá tato lekce: jak je psát, jak jich vytvořit hodně stejného druhu a jak je naučit spolupracovat s print, ==, < a +.

Typická chyba je zapomenutý argument. Při volání farma.popis() nedostane parametr f žádnou hodnotu, a je tedy nil:

local farma = {nazev = "Farma Slunečnice", mince = 120}

function farma.popis(f)
    print(f.nazev .. ": " .. f.mince .. " mincí")
end

farma.popis()

Program skončí chybou:

main.lua:4: attempt to index a nil value (local 'f')

Indexovat znamená číst klíč pomocí . nebo [ ]. f.nazev se pokouší přečíst klíč nazev z f, jenže z nil nejde přečíst nic.

Pokyny

Ve stodole na Emině farmě jsou vejce a mléko. Přidejte funkci stodola.vypis(s), která vypíše, co je ve stodole s, a zavolejte ji: stodola.vypis(stodola). Program vypíše:

Stodola: 12 vajec, 4 litry mléka

Přidejte funkci stodola.pridejVejce(s, pocet), která do stodoly s přidá pocet vajec.

Slepice snesly dalších 6 vajec. Na konci programu je přidejte voláním stodola.pridejVejce(stodola, 6) a znovu vypište obsah stodoly:

Stodola: 12 vajec, 4 litry mléka
Stodola: 18 vajec, 4 litry mléka

Začněte programovat zdarma

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

Nebo se registrujte pomocí:

1/9