5. 6. 2014

Třídy a objekty v jazyce Lua

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: