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

Lua
Кляса языка: Шматпарадыгмавая: скрыптовая, імпэратыўная (працэдурная, прататыпная, аб'ектна-арыентаваная), функцыянаяльная, падтрымлівае мэтапраграмаваньне, рэфлектыўная
Зьявілася ў: 1993 г.
Аўтар(ы): Рабэрту Ерусалімскі
Луіс Энрыке дэ Фігуэйрэда
Вальдэмар Салес
Тыпізацыя дадзеных: Дынамічная, слабая, качыная
Рэалізацыі: Lua, LuaJIT, LuaVela, MoonSharp, Luvit, LuaRT, Luau
Дыялекты: Metalua, Idle, GSL Shell
Уплыў ад: C++, CLU, Modula, Scheme, SNOBOL
Уплыў на: GameMonkey, Io, Julia, MiniD, Red, Ring,[1] Squirrel, MoonScript, C--
АС: Кросплятформавая
Ліцэнзія: MIT License
Афіцыйная старонка: www.lua.org

Гісторыя

рэдагаваць

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

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

Папярэднікамі Lua былі мовы SOL (Simple Object Language - простая аб'ектная мова) і DEL (Data-Entry Language - мова ўводу даных).[6] Яны былі незалежна распрацаваны ў 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.[7]

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

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

Асаблівасьці

рэдагаваць

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

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

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

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

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

print("Hello, World!")
print "Hello, World!"

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

-- аднарадковы камэнтар

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

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

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 патрабуе ўсіх трох ключавых слоў:

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

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

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

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

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

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

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

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

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

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

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

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

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 змененыя:

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

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

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

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, аснова усіх тыпаў, ствараемых карыстальнікамі. Яна ўяўляе сабой асацыятыўны масіў з наданьнем аўтаматычнага лічбавага ключа і спецыяльнага сынтаксу.

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

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

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

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

-- новая табліца з адным значэньнем 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 мае спецыяльны сынтакс для доступу да такіх палёў.[9]

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

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

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

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".

-- індэксы задаюцца аўтаматычна
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 значэнню (гэта значыць, ён можа разглядаць любое такое нулявое значэнне як канец масіва).[10]

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

print(ExampleTable[1][3]) -- друкуе "3"
print(ExampleTable[2][4]) -- друкуе "8"

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

-- канструктар 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 аптымізаваны для выкарыстаньня ў якасці масіваў, каб пазбегнуць гэтай праблемы.[11]

Мэтатабліцы

рэдагаваць

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

-- пачатковыя значэньні 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. Новыя аб'екты ствараюцца альбо фабрычным мэтадам (які стварае новыя аб'екты з нуля), альбо шляхам кланаваньня існуючага аб'екта.

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

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).

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

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 таксама магчыма з дапамогай мэтатабліц.[12] У наступным прыкладзе апэрацыя памнажэньня вэктара на канстанту рэалізаваная ў вытворнай клясе.

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 можа быць функцыяй або табліцай.[13] Перагрузка апэратара таксама можа быць зроблена; мэтатабліцы Lua могуць мець такія элементы, як __add, __sub і гэтак далей.[14]

Рэалізацыя

рэдагаваць

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

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

Наступны прыклад - гэта байт-код функцыі фактарыялу, рэалізаванай вышэй (згодна з кампілятарам luac 5.1):[16]

function <factorial.lua:1,7> (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

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

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

Вось прыклад выкліку функцыі Lua з 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;
}

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

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

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

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

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

рэдагаваць

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

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

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

  1. ^ Ring Team (5 December 2017) Мова праграмаваньня Ring і іншыя мовы (анг.) ring-lang.net Архіўная копія ад 25 December 2018 г.
  2. ^ а б Рабэрту Ерусалімскі, Луіс Энрыке дэ Фігуэйрэда, Вальдэмар Салес Пашыраемая мова пашырэньняў Lua  (анг.) = Lua—An Extensible Extension Language // Software: Practice and Experience. — June 1996. — Т. 26. — С. 635–652. — DOI:10.1002/(SICI)1097-024X(199606)26:6<635::AID-SPE26>3.0.CO;2-P
  3. ^ а б в Пра Lua (анг.). www.lua.org.
  4. ^ Юры Тахцееў (21 April 2013) З Бразыліі ў Вікіпэдыю (анг.) Foreign Affairs
  5. ^ а б Рабэрту Ерусалімскі, Луіс Энрыке дэ Фігуэйрэда, Вальдэмар Салес Эвалюцыя Lua = The evolution of Lua. — 2007. — С. 2–1–2–26. — ISBN 978-1-59593-766-7
  6. ^ Эвалюцыя мовы пашырэньня: гісторыя Lua (анг.). www.lua.org (2001).
  7. ^ Рабэрту Ерусалімскі, Луіс Энрыке дэ Фігуэйрэда, Вальдэмар Салес Скрыптовая мова Lua. Як некалькі мэтафункцый вырашаюць шмат праблем  (анг.) = Lua: an Extensible Embedded Language. A few metamechanisms replace a host of features // Dr. Dobb's Journal. — December 1996. — Т. 21. — С. 26–33.
  8. ^ Праграмаваньне з Lua: 1 (анг.)
  9. ^ Даведачны дапаможнік Lua 5.1 (анг.). www.lua.org (2014).
  10. ^ Даведачны дапаможнік Lua 5.1 (анг.). www.lua.org (2012).
  11. ^ Зыходны код Lua 5.1. www.lua.org (2006).
  12. ^ Рабэрту Ерусалімскі Праграмаваньне з Lua, 4-е выданьне = Programming in Lua, 4th Edition. — С. 165.
  13. ^ Праграмаваньне з Lua: 16.3 (анг.). www.lua.org (2021-09-16).
  14. ^ Практычны ўрок па мэтамэтадам (анг.) Архіўная копія ад Sep 16, 2021 г.
  15. ^ Рабэрту Ерусалімскі, Луіс Энрыке дэ Фігуэйрэда, Вальдэмар Салес Рэалізацыя Lua 5.0  (анг.) = The implementation of Lua 5.0 // J. Of Universal Comp. Sci.. — 2005. — В. 10.3217/jucs-011-07-1159. — Т. 11. — С. 1159–1176.
  16. ^ Кэйн-Гонг Ман (2006) Кароткія ўводзіны ў набор камандаў віртуальнае машыны Lua 5.1 (анг.)
  17. ^ а б Даведачны дапаможнік Lua 5.2 (анг.). www.lua.org.
  18. ^ Зьмены ў API (анг.) Даведачны дапаможнік Lua 5.2. www.lua.org.
  19. ^ Даведачны дапаможнік Lua 5.4 (анг.) www.lua.org
  20. ^ LuaRocks (анг.). luarocks.org.
  21. ^ Чаму Lua лічыцца мовай для відэа-гульняў? (анг.) Stack Overflow Архіўная копія ад 20 August 2013 г.
  22. ^ Чаму Luau? (анг.) luau-lang.org
  23. ^ Уводзіны ў модынг сэрвэра Crysis (анг.) crymp.net
  24. ^ Прызначэньне Lua (анг.) wow.gamepedia.com

Зьнешнія спасылкі

рэдагаваць