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