Programovací jazyk Lua, přestože jako jediný složený datový typ nabízí tabulky, umožňuje i objektové programování. Klasický příklad lze nalézt v Programming in Lua : 16.2:
Account = {balance = 0} function Account:new (o) o = o or {} setmetatable(o, self) self.__index = self return o end function Account:deposit (v) self.balance = self.balance + v end function Account:withdraw (v) if v > self.balance then error"insufficient funds" end self.balance = self.balance - v end
Takovouto třídu pak můžeme použít následujícím způsobem:
a = Account:new() a:deposit(1) a:withdraw(1)
Co přesně se ale odehraje? Pojďme se na to podívat řádek po řádku.
a = Account:new() -- nebo také a = Account.new(Account)
Voláme funkci new
z tabulky Account
. Této funkci předáváme do self
parametru tabulku Account
a parametr o
zůstává nil
. Do proměnné o
se dosadí prázdná tabulka a této tabulce se jako metatabulka nastaví Account
. Zároveň se Account
dosadí sobě do proměnné __index
.
a:deposit(1) -- nebo také a.deposit(a, 1)
V tabulce a
se hledá funkce deposit
, která tam však není, takže se v metatabulce Account
najde tabulka __index
(což je taktéž Account
) a hledá se tam. Funkce je nalezena a zavolána.
Ve funkci deposit
se hledá položka self.balance
(konkrétně a.balance
), která však neexistuje, takže následuje stejná hledací procedura (metatabulka.__index.balance
). Nalezená proměnná Account.balance
obsahuje nulu a tato hodnota se použije.
Následně se k nalezené hodnotě přičte v
a výsledek se dosadí do proměnné self.balance
(konkrétně a.balance
). Tato proměnná neexistuje a je vytvořena.
a:withdraw(1) -- nebo také a.withdraw(a, 1)
V této funkci používáme položku self.balance
(konkrétně a.balance
), která však už existuje a rovnou se použije. K žádnému složitému dohledávání už nedochází.
Na první pohled působí zvláštně, že objektová proměnná se nevytváří už v konstruktoru, ale až při prvním dosazení. Do té doby ji zastupuje proměnná ve třídě, která poskytuje výchozí hodnotu. Nicméně výsledné chování je správné a funguje podle očekávání.
Žádné komentáře:
Okomentovat