Lua
Lua je odlehčený, vysokoúrovňový, reflexivní, multiparadigmatický, imperativní a procedurální programovací jazyk navržený jako skriptovací jazyk s rozšiřitelnou sémantikou. Název je odvozen z portugalského slova pro měsíc. HistorieLua vytvořili v roce 1993 Roberto Ierusalimschy, Luiz Henrique de Figueiredo a Waldemar Celes, členové Computer Graphics Technology Group (Skupina technologie počítačové grafiky) na Papežské univerzitě v Rio de Janeiro v Brazílii. Verze Lua předcházející verzi 5.0 byly uveřejněny pod licencí podobnou BSD licenci, od verze 5.0 je Lua distribuován pod licencí MIT. Lua byl použit v mnoha komerčních aplikacích (např. v adventuře firmy LucasArts Escape from Monkey Island a software ovládajícím roboty) stejně jako těch nekomerčních (Angband a jeho varianty). Mezi jeho nejbližší příbuzné lze řadit Icon pro jeho design a Python pro snadnost použití i pro neprogramátory. V roce 2008 bylo vytvořeno jedno z nejznámějších vývojových prostředí pro jazyk Lua (Corona SDK). V roce 2009 byl vytvořen engine pro 2D hry Love2D. VlastnostiJazyk Lua je určen jako rozšiřující nebo skriptovací jazyk a je dostatečně malý, aby se vešel na nejrůznější hostitelské platformy. Podporuje jen malé množství atomárních datových struktur jako jsou boolovské hodnoty, čísla (implicitně s dvojitou přesností plovoucí čárky) a řetězce. Běžné datové struktury jako jsou pole, množiny, hashovací tabulky, seznamy a záznamy mohou být reprezentovány použitím jediné nativní datové struktury – tabulky, která je v podstatě heterogenním asociativním polem. Jmenné prostory a objekty mohou být vytvořeny taktéž za použití tabulek. Zahrnutím minimálního počtu datových typů se Lua pokouší dosáhnout rovnováhy mezi silou a velikostí. Sémantika Lua může být rozšiřována a měněna předefinováním některých zabudovaných funkcí v metatabulkách. Navíc podporuje Lua pokročilé vlastnosti, jako jsou funkce vyššího řádu a garbage collector. Kombinací mnoha těchto vlastností je možné v Lua psát i objektově orientované programy. Lexikální konvenceV Lua může být jméno (také nazývané identifikátor) jakýkoli řetězec písmen, čísel a podtržítek, který nezačíná číslicí. Tato definice je v souladu s definicí jmen ve většině jazyků. Definice písmene závisí na jazyce (místním): současný jazyk považuje jakýkoli znak písmene za použitý jako identifikátor. Identifikátory se používají k pojmenování proměnných a polí tabulky.[1] Následující klíčová slova jsou vyhrazena a nelze je použít jako identifikátory:
Lua rozlišuje velká písmena od malých; takže Následující řetězce označují další lexikální symboly:
Ukázky kóduDeklarace a inicializace proměnných: local a, b, c = true, "string", 1
Klasický program Hello world lze napsat následovně: print('Hello, world!')
Cyklus for (For loop), který vypíše čísla 1 až 10, lze napsat následovně: for i = 1, 10 do
print(i)
end
Jiný krok než 1 je třeba uvést jako třetí hodnotu před for i = 100, 0, -5 do
print(i)
end
Algoritmus TBKlocal function f(t)
return math.sqrt(math.abs(t)) + 5 * t ^ 3
end
local a = {}
for i = 1, 11 do
a[i] = io.read("*number")
end
for i = #a, 1, -1 do
local y = f(a[i])
print(i - 1, y > 400 and "TOO LARGE" or y)
end
FunkceVýpočet faktoriálu ukazuje rekurzivní volání funkce: function factorial(n)
if n <= 0 then
return 1
end
return n * factorial(n - 1)
end
Výpočet prvních n dokonalých čísel: function perfeitos(n)
cont=0
x=0
print("Dokonalá čísla jsou:")
repeat
x=x+1
suma=0
for i=1,(x-1) do
if math.mod(x,i)==0 then suma=suma+i;
end
end
if suma == x then
print(x)
cont = cont+1
end
until cont==n
print("Stiskněte libovolnou klávesu pro ukončení...")
end
V Lua jsou funkce objekty první kategorie. Následující příklad ukazuje, jak je možné modifikovat chování funkce do
local oldprint = print -- uloží "print" do "oldprint"
print = function(s) -- předefinuje funkci "print"
if s == "foo" then
oldprint("bar")
else
oldprint(s)
end
end
end
Jakékoli volání funkce Uzávěry a možnost funkce v proměnné („prvotřídní“ funkce): function make_adder(x)
return function(a)
return a+x
end
end
add7 = make_adder(7)
r = add7(3) -- => r == 10
Při každém vyvolání funkce Funkce v jazyce Lua jsou pouze jednou kategorií proměnných. Lze je definovat také takto: local foo = function(a,b,c)
print('variable "foo"')
end
Nebo mohou být v tabulkách: local myTable = {'item 1', function() print('table item 2') end, 3}
Příkazy cykluJazyk Lua má 4 typy cyklů: while (s testem na začátku), repeat (s testem na konci), for a generickou smyčku. Jejich syntaxe jsou uvedeny níže: while podmínka do
-- příkazy
end
repeat
-- příkazy
until podmínka
for i = začátek, konec, krok do -- krok může být kladný i záporný
-- příkazy
-- např.: print(i)
end
for key, value in next, some_table do
-- příkazy
end
Generická smyčka projde všemi dvojicemi (klíč,hodnota) v tabulce. Podobný typ smyčky je v jazyce Python. Následuje jednoduchý příklad použití: TabulkyTabulky jsou nejdůležitější datovou strukturou (a jediným složeným datovým typem) v jazyce Lua a jsou základem dalších datových typů. Pomocí tabulek je možné simulovat vektory, matice, struktury, objekty atd. Tabulka je sada klíčů a datových párů známých také jako hashované heterogenní asociativní pole, kde jsou data odkazována klíčem. Klíč (index) může být jakéhokoli datového typu kromě Tabulky se vytvářejí pomocí následující syntaxe: a_table = {} -- vytvoří novou prázdnou tabulku
Při přiřazení se tabulky předávají referencí: a_table = {x = 10} -- vytvoří novou tabulku, která obsahuje jednu dvojici klíč-hodnota, klíči "x" je přiřazena hodnota 10
print(a_table["x"]) -- vypíše hodnotu přiřazenou klíči "x", což je 10
b_table = a_table
a_table["x"] = 20 -- hodnota přiřazená klíči "x" v tabulce a_table se změní na 20
print(a_table["x"]) -- vypíše hodnotu přiřazenou klíči "x" v tabulce a_table, což je 20
print(b_table["x"]) -- vypíše hodnotu přiřazenou klíči "x" v tabulce b_table, což je také 20, protože příkazem b_table = a_table se předal odkaz na tabulku
Tabulky jako vektorPokud se při vytváření tabulky zadají pouze hodnoty, budou jim přiřazeny celočíselné klíče, které je identifikují. Na rozdíl od jiných programovacích jazyků má však první index hodnotu 1, nikoli 0. Následuje příklad, jak můžete simulovat použití vektoru pomocí tabulky v Lua: array = { "a", "b", "c", "d" } -- hodnotám jsou automaticky přiřazeny klíče 1, 2, 3, 4
print(array[2]) -- vypíše "b"
print(#array) -- vypíše 4, operátor # dává poslední index, který je kladné celé číslo
array[0] = "z" -- index 0 není součástí seznamu, ale asociativního pole
print(#array) -- vypíše 4, poslední index, který je kladné celé číslo
Vymazání prvku, iterátorPřiřazením hodnoty array = { "a", "b", "c", "d" } -- hodnotám jsou automaticky přiřazeny klíče 1, 2, 3, 4
print(array[2]) -- vypíše "b"
array[2] = nil
print(#array) -- vypíše 4
array[4] = nil
print(#array) -- vypíše 1
for key, value in pairs(array) do
print(string.format("%s: %s", key, value))
end
Tabulky jako strukturaTabulky se často používají jako struktury, ve kterých jsou jednotlivé položky rozlišeny pomocí identifikátorů. Lua má speciální syntaxi pro přístup k těmto položkám. Příklad: point = { x = 10, y = 20 } -- vytvoří novou tabulku
print(point["x"]) -- vypíše hodnotu položky s klíčem "x", to jest 10
print(point.x) -- jiný způsob přístupu k téže položce
Příklad vektoru struktur: function Point(x, y) -- konstruktor objektů "Point"
return { x = x, y = y } -- vytvoří a vrátí objekt (tabulku)
end
array = { Point(10, 20), Point(30, 40), Point(50, 60) } -- vytvoří pole objektů "Point"
print(array[2].y) -- vypíše 40 (y-ová souřadnice 2. prvku pole array)
Tabulka jako maticePříklad tabulky simulující jednoduchou matici: matice =
{
{1, 2, 3, 4},
{5, 6, 7, 8}
}
print(matice[1][3]) -- vypíše 3 (3. položka z 1. řádku)
print(matice[2][4]) -- vypíše 8 (4. položka z 2. řádku)
Tabulky jako objektyPřestože součástí jazyka Lua nejsou objekty, jazyk lze o toto paradigma rozšířit díky dvěma jeho rysům: tabulkám a faktu, že funkce jsou objekty první kategorie. Objekt se vytvoří umístěním funkcí a souvisejících dat do tabulky. Pomocí metatables lze také implementovat koncept dědičnosti a požádat objekt, aby hledal metody nebo atributy, které v nadřazených objektech neexistují. Následně bude jako příklad vytvořen vektorový objekt, pomocí zjednodušené syntaxe, kterou jazyk poskytuje pro OOP: local Vektor = { } -- vytvoří třídu "Vektor"
Vektor.__index = Vektor
function Vektor:new(x, y, z) -- konstruktor
return setmetatable({x = x, y = y, z = z}, Vektor)
end
function Vektor:magnitude()
-- na atributy objektu se odkazujeme pomocí "self"
return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end
local vec = Vektor:new(0, 1, 0) -- vytvoří objekt třídy Vektor
print(vec:magnitude()) -- volání metody (vypíše 1)
print(vec.x) -- přístup k atributu (vypíše 0)
Další příklad konstrukce třídy a objektově orientovaného programování lze vidět níže. local Vektor = { }
do -- nový blok
Vektor.init = function(x, y, z) -- konstruktor
self = setmetatable({ x = x, y = y, z = z }, {__index=Vektor})
return self
end
function Vektor:magnitude() -- metoda objektu
return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end
end
local vec = Vektor.init(0, 1, 0) -- vytvoří objekt třídy Vektor
print(vec:magnitude()) -- volání metody (vypíše 1)
print(vec.x) -- přístup k atributu (vypíše 0)
Jazyk Lua je natolik flexibilní, intuitivní a dynamický, že může implementovat téměř jakýkoli koncept z jiných programovacích jazyků, který v jazyce Lua chybí; použijí se metatables. MetatablesZákladním rysem jazyka Lua je rozšiřitelná sémantika a koncept „metatables“, který umožňuje rozsáhlé přizpůsobování tabulek jazyka Lua. Následující příklad ukazuje „nekonečnou“ tabulku. Pro jakoukoli hodnotu „n“ je „fibs[n]“ n-té Fibonacciho číslo získané pomocí dynamického programování. fibs = { 1, 1 } -- počáteční hodnoty fibs[1] a fibs[2]
meta_table = setmetatable(fibs, {
__index = function(name, n) -- __index je předdefinovaná funkce, která se vyvolá, pokud klíč "n" neexistuje
name[n] = name[n - 1] + name[n - 2] -- spočítá a vypíše fibs[n].
return name[n]
end
})
print (meta_table[3]) -- vypíše 2
Vnitřní postupyProgramy v Lua nejsou přímo interpretovány, ale jsou kompilovány do bajtkódu, který je následně spuštěn na Lua virtual machine (virtuálním stroji). Proces kompilace je obvykle pro uživatele transparentní a je prováděn za běhu programu. Lze jej však vyvolat offline za účelem zvýšení výkonu nebo omezení velikosti obrazu v paměti hostujícího prostředí vynecháním kompilátoru. Následující příklad ukazuje výpis bajtkódu výše popsané funkce pro výpočet faktoriálu (v Lua 5.1): function <factorial.lua:1,7> (10 instructions, 40 bytes at 0x805ee50)
1 param, 3 slots, 0 upvalues, 1 local, 3 constants, 0 functions
1 [2] LE 0 0 -1 ; compare value to 0
2 [2] JMP 2 ; to line 5
3 [3] LOADK 1 -2 ; 1
4 [3] RETURN 1 2
5 [6] GETGLOBAL 1 -3 ; factorial
6 [6] SUB 2 0 -2 ; - 1
7 [6] CALL 1 2 2
8 [6] MUL 1 0 1
9 [6] RETURN 1 2
10 [7] RETURN 0 1
AplikaceLua se uplatňuje především v mnoha hrách, jako je World of Warcraft, masivní onlinová multiplayerová hra na hrdiny, ve které si mohou uživatelé přizpůsobit uživatelské rozhraní, animace postav a vzhled světa právě v jazyku Lua, a sérii Baldur's Gate a videohře MDK2, kde je použit jako skriptovací jazyk pro moduly. Také se objevuje v některých open source hrách, jakými jsou Bitva o Wesnoth, Daimonin a hry ve stylu Rogue: ToME a H-World. Skripty v jazyce Lua jsou také využity u her Worms 3D, Worms 4: Mayhem, Mafia II, Roblox a v modifikaci pro GTA V, FiveM. Therescript, použitý k řízení vozidel a animací v There, je mírně upravená verze Lua. Správce oken Ion nebo Awesome používají Lua pro své přizpůsobování a rozšiřování. Program Chat Mapper pro zapisování a ukládání rozhovorů (například mezi postavami ve hrách) používá jazyk Lua k řízení rozhovoru. Program LuaTeX rozšiřuje primitivní příkazy TeXu o možnost zadávání kódu v jazyce Lua. Je udržován seznam projektů, o nichž se ví, že používají Lua.[2] KnihyOdkazyReferenceV tomto článku byl použit překlad textu z článku Lua (linguagem de programação) na portugalské Wikipedii.
Externí odkazy
|