Záhony jako objekty

Záhon je záznam a pracují s ním dvě funkce: zahonRoste a popisZahon. Data a funkce, které s nimi pracují, k sobě patří, a právě na to je třída, jako v lekci o objektech. V tomto kroku se ze záhonů stanou objekty třídy Zahon. Program bude dělat přesně totéž co dosud a jeho výstup se vůbec nezmění. Jen jeho kód bude úhlednější. Změně toho, jak je program napsaný, beze změny toho, co dělá, se říká refaktoring a programátoři ho dělají pořád.

Připomeňte si, jak třída funguje, na jedné z Eminých slepic:

local Slepice = {}
Slepice.__index = Slepice

function Slepice.new(jmeno)
    local slepice = {jmeno = jmeno, vejce = 0}
    return setmetatable(slepice, Slepice)
end

function Slepice:snes(pocet)
    self.vejce = self.vejce + pocet
end

function Slepice:__tostring()
    return self.jmeno .. " (vejce: " .. self.vejce .. ")"
end

local zlatka = Slepice.new("Zlatka")
zlatka:snes(2)
zlatka:snes(1)
print(zlatka)
print("Nejlepší slepice: " .. tostring(zlatka))

Vypíše:

Zlatka (vejce: 3)
Nejlepší slepice: Zlatka (vejce: 3)

Slepice.new vytvoří tabulku s daty slepice, dá jí metatabulku Slepice a vrátí ji: setmetatable vrací tabulku, kterou dostala. Díky Slepice.__index = Slepice hledá slepice klíč, který sama nemá (třeba snes), v tabulce Slepice. Dvojtečka ve zlatka:snes(2) předá jako self samotnou slepici. A __tostring říká, co ze slepice udělá print a tostring (používá ji i %s ve string.format). Ale .. ji nevolá, takže "Nejlepší slepice: " .. zlatka by skončilo chybou. Proto příklad volá tostring(zlatka).

Totéž platí pro table.concat. Když do seznamu dne přidáte samotné záhony místo jejich textů, program skončí:

main.lua:108: invalid value (table) at index 1 in table for 'concat'

Do seznamu proto přidávejte tostring(zahon). Další chybou je tečka místo dvojtečky. zahon.roste(rust[dnes]) předá jako self počet dní a z čísla metoda klíč přečíst neumí:

main.lua:44: attempt to index a number value (local 'self')

Sklizeň v hlavním programu může zůstat, jak je. Objekt je pořád tabulka, takže zahon.dnyRustu a zahon.plodina fungují jako dřív.

Pokyny

Pod najdiPlodinu vytvořte třídu Zahon: local Zahon = {} a Zahon.__index = Zahon. Pak napište Zahon.new(plodina, seminka), která vytvoří tabulku {plodina = plodina, seminka = seminka, dnyRustu = 0}, pomocí setmetatable jí dá metatabulku Zahon a vrátí ji.

Z obou funkcí udělejte metody. Zahon:roste(prirustek) dělá totéž co zahonRoste, jen se self místo zahon, a Zahon:__tostring() vrátí stejný text jako popisZahon.

Použijte třídu v hlavním programu: zasejte pomocí Zahon.new(plodina, polozka.seminka), nechte záhony růst pomocí zahon:roste(rust[dnes]) a do seznamu dne přidávejte tostring(zahon). Pak smažte funkce zahonRoste a popisZahon, protože je už nic nepotřebuje. (Kdyby někde zůstalo volání jedné z nich, program by skončil s hláškou attempt to call a nil value (global 'zahonRoste').) Výstup zůstane přesně stejný jako v minulém kroku:

CENÍK
mrkev: semínko za 2, prodej za 5
dýně: semínko za 5, prodej za 20
jahody: semínko za 4, prodej za 12
pšenice: semínko za 1, prodej za 3
Záhon 1: mrkev x4 za 8 mincí
Záhon 2: pšenice x6 za 6 mincí
Záhon 3: dýně x2 za 10 mincí
Na jahody x2 nemá Ema dost mincí
Mince: 6
Den 1 (slunečno): mrkev 1/3, pšenice 1/2, dýně 1/6
Den 2 (slunečno): mrkev 2/3, pšenice 2/2, dýně 2/6
Den 3 (déšť): mrkev 3/3, pšenice 2/2, dýně 4/6
Den 4 (zataženo): mrkev 1/3, pšenice 1/2, dýně 5/6
Den 5 (slunečno): mrkev 2/3, pšenice 2/2, dýně 6/6
Den 6 (zataženo): mrkev 3/3, pšenice 1/2, dýně 1/6
Trh: dýně 2 x 20, mrkev 8 x 5, pšenice 18 x 3 = 134
Konec sezóny: 140 mincí

Začněte programovat zdarma

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

Nebo se registrujte pomocí:

5/7