Lua

**Lua** (ад партугальскага: lua [ ˈlu(w)ɐ ] «луа», што значыць Месяц) — высокаўзроўневая шматпарадыгмавая скрыптовая мова праграмаваньня. Lua з’яўляецца кросплятформавай, паколькі інтэрпрэтатар скампіляванага байт-кода напісаны на ANSI C, і Lua мае адносна простае C API для ўбудаваньня яго ў дадаткі.

## Гісторыя
Lua была створаная ў 1993 годзе Рабэрту Ерусалімскім, Луісам Энрыке дэ Фігуэйрэда і Вальдэмарам Салесам, удзельнікамі Tecgraf (Computer Graphics Technology Group — групы тэхналёгій кампутарнай графікі) у Папскім каталіцкім унівэрсытэце Рыа-ды-Жанейра ў Бразіліі.

З 1977 па 1992 год у Бразілія праводзіла палітыку жорсткіх гандлёвых бар’ераў (так званых рынкавых рэзэрваў) у дачыненьні да кампутарнага абсталяваньня і праграмнага забеспячэньня, мяркуючы, што Бразілія можа і павінна вырабляць іх сама. З-за чаго кліенты Tecgraf не маглі дазволіць сабе, ні палітычна, ні фінансава, купляць індывідуальнае праграмнае забеспячэньне з-за мяжы; згодна з рынкавым рэзэрвам, кліенты павінны былі б прайсьці праз складаны бюракратычны працэс, каб даказаць, што іх патрэбы не могуць быць задаволеныя бразільскімі кампаніямі. Гэта вымусіла Tecgraf ствараць неабходныя інструмэнты з нуля.

Папярэднікамі Lua былі мовы *SOL* (Simple Object Language — простая аб’ектная мова) і *DEL* (Data-Entry Language — мова ўводу даных). Яны былі незалежна распрацаваны ў Tecgraf у 1992—1993 гадах, каб дадаць некаторую гнуткасць у два розныя праекты (абодва былі інтэрактыўнымі графічнымі праграмамі для кампаніі Petrobras). У SOL і DEL не хапала структур кіравання патокам, і Petrobras адчувала ўсё большую патрэбу ў тым, каб дадаць да іх поўную магутнасць праграмаваньня.

Lua 1.0 была распрацаваны такім чынам, што яго канструктары аб’ектаў, якія ў той час крыху адрозьніваліся ад цяперашняга лёгкага і гнуткага стылю, уключалі сынтакс апісаньня даных SOL (адсюль назва Lua: *Sol* азначае «Сонца» на партугальскай мове, а *Lua* азначае «Месяц»). Сынтакс Lua для структур кіраваньня ў асноўным быў запазычаны з Modula (`if`, `while`, `repeat` / `until`), але таксама паспытаў уплыў CLU (множныя прызначэнні і множныя вяртанні з функцый, як больш простая альтэрнатыва спасылачным параметрам або яўным указальнікам), C++ («выдатная ідэя дазволіць лякальнай зьменнай быць аб’яўленай толькі там, дзе яна патрэбна»), SNOBOL і AWK (асацыяцыйныя масівы). У артыкуле, апублікаваным у *часопісе Dr. Dobb’s Journal*, стваральнікі Lua таксама сцвярджаюць, што LISP і Scheme з іх адзінай універсальнай структурай даных (сьпісам) паўплывалі на іх рашэньне выкарыстаць табліцу ў якасьці асноўнай структуры даных Lua.

Зь цягам часу сэмантыка Lua падвяргалася ўсё большаму ўплыву Scheme, асабліва з увядзеньнем ананімных функцый і поўнага лексычнага абсягу. У новых версіях Lua было дададзена некалькі функцый.

Lua да вэрсіі 5.0 выпускалася пад ліцэнзіяй, падобнай да ліцэнзіі BSD. Пачынаючы з вэрсіі 5.0 і далей, Lua распаўсюджваецца па ліцэнзіі MIT. Абедзьве дазваляюць карыстацца Lua бясплатна.

## Асаблівасьці
Lua звычайна апісваюць як шматпарадыгмавую мову, якая мае невялікую базавую функцыянальнасць, якая можа быць пашыраны ў адпаведнасьці з вырашаемай праблемай. Lua не мае яўнай падтрымкі спадкаваньня, але дазваляе рэалізаваць яго з дапамогай мэтатабліц. Аналягічным чынам Lua дае магчымасьць выкарыстоўваць прасторы імёнаў, клясы і іншую функцыянальнасць; першаклясныя функцыі дазваляюць выкарыстоўваць мноства мэтадаў функцыянальнага праграмавання, а поўны лексычны абсяг дазваляе схаваць дэталёвую інфармацыю для выкананьня прынцыпу найменшых прывілеяў.

Увогуле, Lua імкнецца прадастаўляць простыя, гнуткія мэтафункцыі, якія можна пашыраць па меры неабходнасці, а не набор функцый, характэрны для адной парадыгмы праграмаваньня. У выніку базавая мова выкарыстоўвае невялікі аб’ём памяці; скампіляваны інтэрпрэтатар займае толькі каля 247&nbsp;kB.

Як мова з дынамічнай тыпізацыяй, прызначаная для выкарыстання ў якасці мовы сцэнарыяў, Lua досыць кампактная, каб змясьціцца на розных хост-плятформах. Яна падтрымлівае толькі невялікую колькасць простых тыпаў даных, такіх як булевыя значэньні, лічбы (па змаўчаньні з плаваючай кропкай падвойнай дакладнасьці і 64-бітныя цэлыя) і радкі. Тыповыя структуры даных, такія як масівы, сэты, сьпісы і запісы, могуць быць прадстаўлены з дапамогай адзінай уласнай структуры даных Lua — табліцы, якая па сутнасьці з’яўляецца гетэрагенным асацыятыўным масівам.

Lua рэалізуе невялікі набор пашыраных функцый, такіх як першаклясныя функцыі, зборка смецьця, замыканьні, правільныя хваставыя выклікі, пераўтварэньне (аўтаматычнае пераўтварэнне паміж радковымі і лікавымі значэннямі падчас выканання), карутыны (кааператыўная шматзадачнасьць) і дынамічная загрузка модуляў.

### Сынтакс
Клясычная "Hello, World!" праграма можа быць запісана наступным чынам, з дужкамі або без:


```lua
print(«Hello, World!»)
```



```lua
print «Hello, World!»
```


Камэнтар у Lua пачынаецца з падвойнага злучка і працягваецца да канца радка, падобна да Ada, Eiffel, Haskell, SQL і VHDL. Шматрадковыя камэнтары абмежаваныя падвойнымі квадратнымі дужкамі.


```lua
— аднарадковы камэнтар

--[[
    шматрадковы 
    камэнтар
]]
```


У наступным прыкладзе рэалізавана функцыя вылічэньня фактарыялу:


```lua
function factorial(n)
    local x = 1
    for i = 2, n do
        x = x * i
    end
    return x
end
```


### Кіраваньне патокам

Lua мае адзіную канструкцыю галінаваньня: `if then end` з неабавязковым `else` і `elseif then`.

Стандартны апэратар `if then end` патрабуе ўсіх трох ключавых слоў:


```lua
if умова then
 -- сцьвярджэньне
end
```


Ключавое слова `else` можа быць дададзена з суправаджальным блокам апэратараў для кіраваньня выкананнем, калі ўмова `if` вылічваецца як `false`:


```lua
if умова then
    -- сцьвярджэньне
else
    -- сцьвярджэньне
end
```


Множны выбар рэалізуецца канструкцыяй `elseif then`:


```lua
if умова then
    -- сцьвярджэньне
elseif умова then
    -- сцьвярджэньне
else
    -- сцьвярджэньне
end
```


Lua мае чатыры тыпы ўмоўных цыкляў: `while`, `repeat` (падобны на `do while`), лікавы `for` і агульны `for`.


```lua
while умова do
    -- сцьвярджэньне
end

repeat
    -- сцьвярджэньне
until умова

for i = first, last, delta do
    -- delta можа быць адмоўнай, дазваляючы цыклу лічыць у зваротны бок
    -- сцьвярджэньне
end
```


Гэты `for` будзе перабіраць табліцу `_G` з выкарыстаньнем стандартнай функцыі ітэратараў `pairs` пакуль не верне `nil`:


```lua
for key, value in pairs(_G) do
    print(key, value)
end
```


Цыклі таксама могуць быць укладзенымі (змяшчацца ўнутры іншага цыкля).


```lua
local grid = {
    { 11, 12, 13 },
    { 21, 22, 23 },
    { 31, 32, 33 }
}

for y, row in pairs(grid) do
    for x, value in pairs(row) do
        print(x, y, value)
    end
end
```


### Функцыі

Абыходжаньне з функцыяй як сутнасьцю першае клясы паказана ў наступным прыкладзе, дзе паводзіны функцыі `print` змененыя:


```lua
do
    -- захоўваем функцыю print як oldprint
    local oldprint = print

    function print(s)
        -- перанакіроўваем выклік print
        oldprint(s == "foo" and "bar" or s)
    end
end
```


Любыя будучыя выклікі `print` цяпер будуць накіроўвацца праз новую функцыю, з-за лексычнага абсягу Lua старая функцыя `print` будзе даступная толькі цераз новаю зьмененую `print`.

Lua таксама падтрымлівае замыканьні, як паказана ніжэй:


```lua
function addto(x)
    -- вяртаем новую функцыю, якая дадае x да аргумента
    return function(y)
        --[[ Калі мы зьвяртаемся да зьменнай x па-за межамі яе абсягу,  
             Lua робіць замыканьне. ]]
        return x + y
    end
end

fourplus = addto(4)
print(fourplus(3)) — друкуе 7
```


Новае замыканьне для зменнай `x` ствараецца кожны раз, калі выклікаецца `addto`, так што кожная новая вернутая ананімная функцыя будзе заўсёды мець доступ да ўласнага параметра `x`.

### Табліцы

Табліца — адзіны убудаваны складаны тып даных у Lua, аснова усіх тыпаў, ствараемых карыстальнікамі. Яна ўяўляе сабой асацыятыўны масіў з наданьнем аўтаматычнага лічбавага ключа і спецыяльнага сынтаксу.

Табліцы ствараюцца з дапамогай сынтаксу канструктара `{}`.


```lua
a_table = {} — новая пустая табліца
```


Табліцы заўсёды перадаюцца па спасылцы.

Ключ (індэкс) можа быць любым значэньнем, нават функцыяй, але не `nil` і не NaN.


```lua
— новая табліца з адным значэньнем 10 па ключу «x»
a_table = { x = 10 }

— друкуе значэньне па ключу «x», у гэтым выпадку 10
print(a_table["x"])

b_table = a_table

— значэньне у табліцы зьменена на 20
b_table["x"] = 20

— друкуе 20
print(b_table["x"])

— таксама друкуе 20, таму што a_table і b_table спасылаюцца на тую самую табліцу
print(a_table["x"])
```


Табліца часта ўжываецца як структура (або запіс), выкарыстоўваючы радкі ў якасці ключоў. Паколькі такое выкарыстанне вельмі распаўсюджана, Lua мае спецыяльны сынтакс для доступу да такіх палёў.


```lua
point = { x = 10, y = 20 } — новая табліца
print(point["x"]) — друкуе 10

— Тое самае што і радок вышэй. Кропкавая натацыя карацейшая і больш простая для ўспрыманьня.
print(point.x)
```


Табліца можа падысьці у якасьці прасторы імёнаў, калі захоўваць у ёй функцыі.


```lua
Point = {}

Point.new = function(x, y)
    -- вяртае { ["x"] = x, ["y"] = y }
    return {x = x, y = y}
end

Point.set_x = function(point, x)
    -- point["x"] = x
    point.x = x
end
```


Элементам табліцы аўтаматычна надаюцца лічбавыя ключы, што дазваляе выкарыстоўваць табліцы як масівы. Першы аўтаматычны індэкс роўны 1, а не 0, як у многіх іншых мовах праграмавання (але яўны індэкс 0 магчымы).

Лічбавы ключ `1` не тое самае што радковы ключ `"1"`.


```lua
— індэксы задаюцца аўтаматычна
array = { «a», «b», «c», «d» }
 
— Друкуе «b». Аўтаматычныя індэксы ў Lua пачынаюцца з 1.
print(array[2])

— Друкуе 4. # — апэратар памеру для табліц і радкоў.
print(#array)

— нуль — дазволены індэкс
array[0] = «z»

— Усё яшчэ друкуе 4, так як масівы Lua індэксуюцца з 1.
print(#array)
```


Памер табліцы `t` вызначаецца як любы цэлы індэкс `n` такі што `t[n]` не `nil` і `t[n+1]` роўны `nil`; акрамя таго, калі `t[1]` `nil`, `n` можа быць роўным нулю. Для рэгулярнага масіва зь ненулявымі значэньнямі ад 1 да дадзенага `n` яго памер дакладна роўны `n`, індэксу яго апошняга значэння. Калі масіў мае «дзіркі» (нулявыя значэнні паміж іншымі значэннямі, выдатнымі ад нуля), то `#t` можа быць любым з індэксаў, які непасрэдна папярэднічае `nil` значэнню (гэта значыць, ён можа разглядаць любое такое нулявое значэнне як канец масіва).


```lua
ExampleTable =
{
    {1, 2, 3, 4},
    {5, 6, 7, 8}
}

print(ExampleTable[1][3]) — друкуе «3»
print(ExampleTable[2][4]) — друкуе «8»
```


Табліца можа быць масівам аб’ектаў.


```lua
— канструктар Point
function Point(x, y)
    -- вяртаецца новы аб'ект
    return { x = x, y = y }
end

— ствараецца масіў кропак
array = { Point(10, 20), Point(30, 40), Point(50, 60) }

— друкуе 40
print(array[2].y)
```


Выкарыстаньне хэш-табліцы для эмуляцыі масіва звычайна павольней, чым выкарыстаньне фактычнага масіва; аднак табліцы Lua аптымізаваны для выкарыстаньня ў якасці масіваў, каб пазбегнуць гэтай праблемы.

### Мэтатабліцы

Пашыраемая сэмантыка з’яўляецца ключавой асаблівасцю Lua, а канцэпцыя мэтатабліцы дазваляе гібкую наладу табліц. У наступным прыкладзе дэманструецца «бясконцая» табліца. Для любога `n` `fibs[n]` дасць `n`-ы лік Фібаначы з дапамогай дынамічнага праграмаваньня і мэмаізацыі.


```lua
— пачатковыя значэньні fibs[1] і fibs[2].
fibs = { 1, 1 }

setmetatable(fibs, {

    -- __index - спецыяльная функцыя Lua, якая выклікаецца калі табліца не мае пазначанага ключа
    __index = function(values, n)

        -- вылічаем і запамінаем fibs[n]
        values[n] = values[n - 1] + values[n - 2]

        return values[n]
    end
})
```


### Аб’ектна-арыентаванае праграмаванне

Нягледзячы на тое, што Lua не мае ўбудаванай канцэпцыі клясаў, аб’ектна-арыентаванае праграмаванне можа эмулявацца з дапамогай функцый і табліц. Аб’ект фармуецца шляхам размяшчэння мэтадаў і палёў у табліцы. Спадкаваньне (як адзінкавае, так і множнае) можа быць рэалізавана з дапамогай мэтатабліц, дэлегуючы неіснуючыя мэтады і палі бацькоўскаму аб’екту.

У гэтым выпадку такога паняцця як «кляса» не існуе; хутчэй, гэта падобна да прататыпнага спадкаваньня, як у Self або JavaScript. Новыя аб’екты ствараюцца альбо фабрычным мэтадам (які стварае новыя аб’екты з нуля), альбо шляхам кланаваньня існуючага аб’екта.

Стварэнне простага аб’екта, які апісвае вэктар:


```lua
local Vector = {}
local VectorMeta = { __index = Vector }

— Канструктар клясы Vector
function Vector.new(x, y, z)
    return setmetatable({ x = x, y = y, z = z }, VectorMeta)
end

function Vector.magnitude(self)
    return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

— стварэньне новага вэктара
local vec = Vector.new(0, 1, 0)

— выклік мэтада
print(vec.magnitude(vec))

— доступ да поля x
print(vec.x)
```


Тут `setmetatable` загадвае Lua шукаць элемент у табліцы `Vector`, калі ён адсутнічае ў табліцы `vec`. `vec.magnitude`, тое самае што і `vec["magnitude"]`, спачатку шукае элемент `magnitude` у табліцы `vec`. Табліца `vec` не мае элемента `magnitude`, але яе мэтатабліца дэлегуе элемент `magnitude` ў табліцу `Vector`, калі ён не знойдзены ў табліцы `vec`.

Lua мае некаторы сынтаксычны цукар для палягчэньня апісаньня клясы. Каб аб’явіць функцыі-члены ўнутры табліцы-прататыпа, можна выкарыстоўваць `function table:func(args)`, што эквівалентнае `function table.func(self, args)`. Для выкліку мэтадаў клясы таксама можа выкарыстоўваць двукроп’е: `object:func(args)`, тое самае `object.func(object, args)`.

Улічваючы гэта, вось адпаведны клас з `:` сынтаксычным цукрам:


```lua
local Vector = {}
Vector.__index = Vector

— Канструктар клясы Vector
function Vector:new(x, y, z)

    --[[ Так як мэтад створаны пры дапамозе двукроп'я, 
         "self" няяўна перадаецца як першы аргумэнт. ]]
    return setmetatable({ x = x, y = y, z = z }, self)
end

function Vector:magnitude()
    return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

— новы вэктар
local vec = Vector:new(0, 1, 0)

— выклік мэтада
print(vec:magnitude())

— доступ да поля «x»
print(vec.x)
```


#### Спадкаваньне

Спадкаваньне у Lua таксама магчыма з дапамогай мэтатабліц. У наступным прыкладзе апэрацыя памнажэньня вэктара на канстанту рэалізаваная ў вытворнай клясе.


```lua
local Vector = {}
Vector.__index = Vector

--- канструктар клясы Vector
function Vector:new(x, y, z)
    
    --[[ Тут self спасылаецца на тую клясу, мэтад якой выклікаецца. 
         У вытворнай клясе self будзе гэтай самай вытворнай клясай,
         у клясе Vector self будзе Vector. ]]
    return setmetatable({ x = x, y = y, z = z }, self)
end

function Vector:magnitude()
    return math.sqrt(self.x^2 + self.y^2 + self.z^2)
end

local VectorMult = {}
VectorMult.__index = VectorMult

— пазначаем VectorMult нашчадкам клясы Vector
setmetatable(VectorMult, Vector)

function VectorMult:multiply(value)
    self.x = self.x * value
    self.y = self.y * value
    self.z = self.z * value
    return self
end

— ствараем новы вэктар
local vec = VectorMult:new(0, 1, 0)

— выклікаем мэтад, друкуе 1
print(vec:magnitude())

— звяртаемся да поля y, друкуе 1
print(vec.y)

— памнажаем усе складаныя вэктару на 2
vec:multiply(2)

— зноў звяртаемся да поля y, атрымоўваем 2
print(vec.y)
```


Lua таксама падтрымлівае множнае спадкаваньне; `__index` можа быць функцыяй або табліцай. Перагрузка апэратара таксама можа быць зроблена; мэтатабліцы Lua могуць мець такія элементы, як `__add`, `__sub` і гэтак далей.

## Рэалізацыя

Праграма на Lua не інтэрпрэтуецца непасрэдна з тэкставага файла, а кампілююцца ў байт-код, які потым запускаецца на віртуальнай машыне Lua. Увесь працэс звычайна нябачны для карыстальніка і выконваецца падчас працы. Кампіляцыя можа быць выкананы загадзя, каб паскорыць загрузку або, прыбраўшы кампілятар, паменшыць аб’ём памяці хост-асяродьдзя. Кампіляцыя магчыма таксама ўнутры праграмы на Lua з выкарыстаньнем функцыі `dump` з бібліятэкі радкоў альбо адной з функцый `load/loadstring/loadfile`.

У адрозненьне ад большасьці віртуальных машын (якія звычайна стэкавыя), віртуальная машына Lua рэгістравая і больш нагадвае рэальную апаратную канструкцыю. Рэгістравая архітэктура пазбягае празмернага капіравання значэнняў і памяншае агульную колькасць інструкцый на функцыю. Віртуальная машына Lua 5 з’яўляецца адной з першых чыста рэгістравых віртуальных машын, якія атрымалі шырокае прымяненьне.

Наступны прыклад — гэта байт-код функцыі фактарыялу, рэалізаванай вышэй (згодна з кампілятарам `luac` 5.1):
 
 function  (9 instructions, 36 bytes at 0x8063c60)
 1 param, 6 slots, 0 upvalues, 6 locals, 2 constants, 0 functions
 	1	[2]	LOADK    	1 -1	; 1
 	2	[3]	LOADK    	2 -2	; 2
 	3	[3]	MOVE     	3 0
 	4	[3]	LOADK    	4 -1	; 1
 	5	[3]	FORPREP  	2 1	    ; to 7
 	6	[4]	MUL      	1 1 5
 	7	[3]	FORLOOP  	2 -2	; to 6
 	8	[6]	RETURN   	1 2
 	9	[7]	RETURN   	0 1

## C API

Lua была распрацавана з мэтай убудаваньня ў іншыя праграмы, дзеля гэтага яна распаўсюджваецца разам з C API. Які складаецца з дзвюх частак: ядро Lua і дапаможнай бібліятэкі Lua. Апошняя складаецца ў асноўным з макрасаў прэпрацэсара, якія дапамагаюць са складанымі таблічнымі апэрацыямі.

Lua C API заснаваны на стэку. Lua забяспечвае функцыі для праштурхоўваньня і выцягваньня большасьці простых тыпаў даных C (цэлыя лікі, плывучыя і г. д.) у стэк і са стэку, а таксама функцыі для маніпуляваньня табліцамі праз стэк. Стэк Lua некалькі адрозніваецца ад традыцыйнага; напрыклад, яго можна непасрэдна праіндэксаваць. Адмоўныя індэксы паказваюць зрушэнні ад вяршыні стэка. Напрыклад, −1 з’яўляецца верхнім (апошняе значэньне), у той час як дадатныя індэксы паказваюць зрушэньні ад ніжняга (самае старое значэньне). Маршалінг даных паміж функцыямі C і Lua таксама выконваецца з дапамогай стэка. Каб выклікаць функцыю Lua, аргументы зьмяшчаюцца ў стэк, а затым `lua_call` выкарыстоўваецца для выкліку Lua функцыі. Пры напісаньні функцыі C для непасрэднага выкліку з Lua аргументы счытваюцца са стэку.

Вось прыклад выкліку функцыі Lua з C:


```c
# include <stdio.h>

// галоўная бібліятэка Lua (lua_*)
# include <lua.h>

// дапаможная бібліятэка Lua (luaL_*)
# include <lauxlib.h>

int main(void)
{
    // пачынае працу з Lua
    lua_State *L = luaL_newstate();

    // загадваем Lua выканаць радок кода, які стварае функцыю foo
    if (luaL_dostring(L, "function foo (x,y) return x+y end")) {
        lua_close(L);
        return -1;
    }

    // захоўваем адрас функцыі foo і лікі 5 і 3 у стэку Lua
    lua_getglobal(L, "foo");
    lua_pushinteger(L, 5);
    lua_pushinteger(L, 3);

    // выклікаем функцыю foo з 2 аргумэнтамі і адным зваротным значэньнем
    lua_call(L, 2, 1);

    // друкуем тое, што знаходзіцца на вяршыні стэку
    printf("Result: %d\n", lua_tointeger(L, -1));

    // вяртаем стэк у першапачатковы стан
    lua_pop(L, 1);

    // завяршаем працу з Lua
    lua_close(L);

    return 0;
}
```


Запуск гэтага прыклада дае:


```console
$ cc -o example example.c -llua
$ ./example
Result: 8
```


C API таксама забясьпечвае некаторыя спецыяльныя табліцы, разьмешчаныя ў розных «псэўдаіндэксах» у стэку Lua. У `LUA_GLOBALSINDEX` да Lua 5.2 знаходзілася глабальная табліца `_G`, якая з’яўляецца асноўнай прасторай імёнаў. Існуе таксама рэестар, размешчаны ў `LUA_REGISTRYINDEX`, дзе праграмы на C могуць захоўваць даныя Lua для пазьнейшага выкарыстаньня.

### Модулі

Акрамя стандартных бібліятэчных (асноўных) модуляў, можна пісаць пашырэнні з дапамогаю Lua API. Скрыпты Lua могуць загружаць модулі пашырэньня з дапамогаю `require`, гэтак жа, як стандартныя модулі самой Lua, або з дапамогаю `package.loadlib`. Калі бібліятэка C загружаецца праз `require('foo')` Lua выклікае функцыю `luaopen_foo`, якая дзейнічае як любая функцыя C, якую можна выклікаць з Lua, і звычайна вяртае табліцу, запоўненую мэтадамі. Модулі Lua, вядомыя пад назваю *rocks,* даступная праз сістэму кіраваньня пакетамі LuaRocks.

## Выкарыстанне

Lua шырока выкарыстоўваецца ў якасці мовы сцэнарыяў у распрацоўцы відэагульняў, галоўным чынам дзякуючы сваёй лёгкасьці ўбудаваньня, хуткаму выкананьню і кароткаму працэсу навучаньня. Сярод вядомых гульняў, якія выкарыстоўваюць Lua, *[[Roblox]]*, *[[Garry's Mod]]*, *[[World of Warcraft]]*, *[[Payday 2]]*, *[[Phantasy Star Online 2]]*, *[[Dota 2]]*, *[[Crysis]]* і многія іншыя. Некаторыя гульні маюць мадыфікацыі, якія падтрымліваюць Lua, напрыклад, ComputerCraft для *[[Minecraft]]*. Акрамя таго, Lua таксама выкарыстоўваецца ў праграмным забеспячэньні, не звязаным з відэагульнямі, такім як Adobe Lightroom, Moho, iClone, Aerospike і пэўным сістэмным праграмным забеспячэнні ў FreeBSD і NetBSD, а таксама выкарыстоўваецца ў якасці шаблённай мовы сцэнарыяў у МэдыяВікі з выкарыстаннем пашырэння Scribunto.

У 2003 годзе апытанне, праведзенае GameDev.net, паказала, што Lua была самай папулярнай мовай сцэнарыяў для праграмаваньня гульняў. 12 студзеня 2012 года Lua быў абвешчаны пераможцам прэміі Front Line Award 2011 ад часопіса *Game Developer* у катэгорыі «Сродкі праграмавання».

Вялікая колькасць негульнявых дадаткаў таксама выкарыстоўвае Lua у якасці мовы сцэнарыяў. Напрыклад, LuaTeX, Redis, ScyllaDB, Neovim, Nginx і Wireshark.

## Крыніцы

## Вонкавыя спасылкі

* [//www.lua.org Афіцыйная старонка]
* Lua Rocks — Пакетны мэнэджар

Катэгорыя:Мовы праграмаваньня, створаныя ў 1993 годзе
Катэгорыя:Прататыпна-арыентаваныя мовы праграмаваньня
Катэгорыя:Скрыптовыя мовы
Катэгорыя:Мовы з дынамічнай тыпізацыяй
Катэгорыя:Вольныя праграмы зь ліцэнзіяй МТІ
Катэгорыя:Бразыльскія вынаходніцтвы
Катэгорыя:Кросплятформавыя вольныя праграмы
Катэгорыя:Вольныя кампілятары і інтэрпрэтатары
Катэгорыя:Вольныя бібліятэкі праграмаў
Катэгорыя:Вольныя праграмы на C