Розширення:Scribunto/Документація мови Lua
Ця довідка документує мову Lua такою, якою вона використовується на MediaWiki з розширенням Scribunto . Деякі частини були взяті з документації Lua 5.1, яка поширюється під ліцензією MIT.
Ця сторінка документує останню версію розширення Scribunto. Деякі функції можуть бути ще не запровадженими. |
Вступ
Як розпочати
Створіть сторінку, яка починається із «Module:» (або «Модуль:» в україномовних проєктах) в будь-якому вікіпроєкті, який використовує рушій MediaWiki, і в якому включене розширення Scribunto, наприклад «Модуль:Bananas». Скопіюйте цей текст в цю сторінку:
local p = {} --p означає «package»
function p.hello( frame )
return "Hello, world!"
end
return p
Збережіть сторінку. Далі відкрийте будь-яку іншу сторінку (спрацює на будь-якій, але рекомендується на сторінці, яка починається із «Template:» або «Шаблон:») і скопіюйте туди такий текст:
{{#invoke:Bananas|hello}}
При цьому замість «Bananas» ви маєте написати назву тільки що створеного вами модуля. Цей текст викликає функцію «hello» з вашого модуля. Після збереження замість {{#invoke:Bananas|hello}}
на екрані буде показуватись текст, який повернула функція, в даному випадку вона поверне текст «Hello, world!».
Вставляти виклики функцій Lua краще у шаблонах. В такому випадку зі сторінки викликається саме шаблон і сторінка не залежить від того чи реалізований шаблон на вікітексті чи за допомогою Lua. Також це дозволяє уникнути складного синтаксису в тексті сторінок основного простору.
Структура модуля
Сам модуль має повертати таблицю, що містить функції які можуть бути викликані через {{#invoke:}}
.
Зазвичай, як це показано вище, оголошується локальна змінна в якій зберігається таблиця. До цієї таблиці додаються функції і в самому кінці коду модуля ця таблиця повертається.
Будь-які функції, які не були додані до таблиці, не залежно від того чи це локальні чи глобальні функції, не будуть доступними через {{#invoke:}}
, але глобальні функції можуть бути доступними в інших модулях при використанні функції require()
.
Оголошення всіх функцій та змінних локальними вважається гарним стилем написання коду.
Доступ до параметрів з вікітексту
Функціям, які викликаються за допомогою {{#invoke:}}
, передається єдиний параметр який є об'єктом фрейму. Щоб отримати доступ до параметрів переданих до {{#invoke:}}
, зазвичай використовується таблиця args
цього об'єкта фрейма. Також можна отримати доступ до параметрів переданих шаблону, який містить {{#invoke:}}
, за допомогою методу frame:getParent()
.
Також за допомогою об'єкта фрейма можна скористатися функціями вікітекстового парсеру, наприклад викликати функцію парсера, викликати шаблон або обробити рядок вікітексту.
Повернення тексту
Функції модуля зазвичай повертають один текстовий рядок. У випадку, якщо функція повертає не текстовий рядок або не одне значення, всі повернуті значення перетворюються на текст за допомогою функції tostring() після чого об'єднуються (конкатенуються) в один рядок без символів розділення. Результуючий рядок включається до вікітексту як результат {{#invoke:}}
.
На цей момент всі шаблони вже мають бути викликаними, всі парсерні функції обробленими, всі перетворення (наприклад перетворення тильд на підпис) виконаними. Модуль не повинен повертати текст, який містить перелічене вище. Наприклад, якщо модуль повертає текст "Hello, [[world]]! {{welcome}}"
, то і на сторінці він відобразиться як «Hello, world! {{welcome}}», а шаблон «welcome» викликаний не буде.
Окрім того, підстановки виконуються на ранній стадії обробки тексту, тому код {{subst:#invoke:}}
не спрацює одразу, а тільки після наступного редагування сторінки де він написаний.
Документація модулів
Scribunto дозволяє документувати модулі, автоматично асоціюючи модуль зі сторінкою документації написаною на вікітексті яка за замовчуванням має назву модуля із доданим «/doc» на кінці, наприклад для «Module:Bananas» сторінка документації буде називатися «Module:Bananas/doc». При перегляді сторінки модуля, його документація автоматично показується перед кодом модуля.
Відображення сторінки документації може бути налаштоване за допомогою повідомлень MediaWiki-простору:
scribunto-doc-page-name
— Встановлює сторінку, яка буде використовуватись як сторінка документації. Назву модуля (без префікса «Module:» або «Модуль:») можна отримати за допомогою кода$1
. Якщо вказана сторінка документації знаходиться в просторі назв «Модуль:», то її вміст інтерпритуватиметься як вікітекст, а не код на Lua. Також на сторінці документації не має бути{{#invoke:}}
. Значенням за замовчуванням є «Module:$1/doc», тобто підстрінка «/doc» модуля. При вказанні назви сторінки документації не можна використовувати шаблони або парсерні функції.scribunto-doc-page-does-not-exist
— Повідомлення, яке буде показуватись, якщо сторінка документації не існує. Ім’я сторінки передається як$1
. За замовчуванням порожній.scribunto-doc-page-show
— Повідомлення відображається, коли сторінка документа існує. Ім’я сторінки передається як$1
. За замовчуванням включається сторінка документації.scribunto-doc-page-header
— Заголовок відображається під час перегляду самої сторінки документації. Назва модуля (з префіксом Module:), що документується, передається як$1
. За замовчуванням просто відображається коротке пояснення курсивом.
Зверніть увагу, що модулі не можуть бути напряму категоризовані і не можуть мати інтервікі-посилання вказані прямо на сторінці.
Категорії та інтервікі-посилання краще вставляти на сторінку документації всередині тегів <includeonly>...</includeonly>
. Тоді вони застосуються до модуля коли сторінка документації буде включена до сторінки модуля.
Renaming or moving modules
To rename or move a module, use the Move Page link in the Tools sidebar. You will want to move both the module itself, as well as the subpage containing its documentation.
To manually create a module redirect, use the following syntax:
return require [[Module:Foo]]
Replace Foo
with the name of the module you'd like to redirect to.
Мова Lua
Назви змінних та ключові слова
Назви (їх також називають ідентифікаторами) в Lua можуть бути будь-яким текстовим рядком, який складається з літер, цифр або знаків підкреслювання і не починається з цифри. Назви є чутливими до регістру, тому «foo», «Foo» та «FOO» є різними назвами.
Ключові слова, які є зарезервованими і не можуть використовуватись як назви:
and
break
do
else
elseif
end
false
for
function
if
in
local
nil
not
or
repeat
return
then
true
until
while
Назви, які починаються із знаку підкреслення та великої літери зарезервовані для внутрішніх змінних Lua.
Операторами в мові Lua є:
#
%
(
)
*
+
,
-
--
.
..
...
/
:
;
<
<=
=
==
>
>=
[
]
^
{
}
~=
Коментарі
Коментар в коді на мові Lua починається з --
будь-де, окрім всередині текстового рядка, і продовжується до кінця рядка. Якщо після --
одразу йде довга відкриваюча дужка, то коментар продовжується до відповідної довгої закриваючої дужки.
-- Коментар в Lua починається з двох дефісів і продовжується до кінця рядка.
--[[ Багаторядковий текст та коментарі
оточують подвійні квадратні дужки. ]]
--[=[ Такі коментарі можуть мати вкладені --[[коментарі]] всередині. ]=]
--[==[ Такі коментарі можуть мати інші вкладені
--[===[ довгі --[=[коментарі]=] --всередині
]===] декілька разів, навіть якщо жоден з них
--[[ не позначений відповідними довгими дужками! ]===]
]==]
Типи даних
Lua є мовою програмування із динамічною типізацією. Це означає що змінні та аргументи функцій не мають типу, тільки їх значення мають тип. Кожне значення має тип.
Lua має вісім типів даних, але тільки шість із них доречно використовувати в розширенні Scribunto. Функція type()
повертає тип переданого їй аргумента.
Функція tostring()
перетворює переданий їй аргумент в текстовий рядок. Функція tonumber()
перетворює переданий їй аргумент в число якщо це можливо, в іншому випадку повертає nil.
Число автоматично перетворюється на текстовий рядок коли це число використовується там, де очікується текстовий рядок, наприклад при використанні оператора об'єднання рядків. Рядки, які можуть бути оброблені функцією tonumber()
, автоматично перетворюються в числа коли до них застосовуються математичні оператори. Коли очікується логічне значення, всі значення окрім nil та false вважаються правдивими.
nil
nil є спеціальним типом nil
, який позначає відсутність значення.
Його не можна використовувати як ключ в таблиці тому що не існує різниці між непозначеним ключем та ключем позначеним значенням nil.
Якщо nil перетворити на текстовий рядоку, то вийде «nil». Якщо його перетворити на логічне значення, то він вважається неправдивим.
Note: Lua does make a distinction between nil
and nothing at all in some limited situations.
For example, tostring(nil)
returns "nil"
, but tostring()
throws an error, as the first parameter is required.
This distinction is particularly relevant to the select() function.
Логічні значення
Існує тільки два логічних значення: true
та false
.
Якщо їх перетворити на текстовий рядок, то вийде відповідно «true» або «false».
На відміну від більшості інших мов програмування, логічні значення не можуть бути перетворені у числа. Також, на відміну від більшості інших мов програмування, тільки false та nil вважаються неправдивими, а всі інші значення, включаючи 0 та порожній текстовий рядок, вважаються правдивими.
Текстові рядки
Текстові рядки в Lua вважаються послідовностями байтів, які інтерпретуються як текст відповідно до певної системи кодування.
Значення рядків починаються і закінчуються одинарними або подвійними лапками ('
або "
). Подібно до JavaScript і на відміну від PHP, між цими двома варіантами лапок немає різниці. Всередині текстового рядка розпізнаються такі керуючі послідовності:
\a
(звуковий сигнал, байтове значення 7)\b
(повернення на крок або backspace, байтове значення 8)\t
(горизонтальна табуляція, байтове значення 9)\n
(зміна рядка, байтове значення 10)\v
(вертикальна табуляція, байтове значення 11)\f
(зміна сторінки, байтове значення 12)\r
(повернення каретки, байтове значення 13)\"
(подвійні лапки, байтове значення 34)\'
(одинарні лапки, байтове значення 39)\\
(обернений слеш, байтове значення 92)
Також зміну рядка можна включити до текстового рядка за допомогою обернененого слеша та власне зміни рядка. Байти також можуть бути вказані через їх числові значення за допомогою керуючих послідовностей виду «\ddd», де «ddd» є десятковим значенням байту в межах 0-255. Щоб за допомогою керуючих послідовностей включити до текстового рядка символи Unicode, треба вказувати окремі байти UTF-8, тому легше включити символи Unicode до текстового рядка прямо написавши їх.
Текстові рядки окрім лапок можуть також починатись і закінчуватись довгими дужками.
Довга відкриваюча дужка складається з відкриваючої квадратної дужки, після якої йде нуль або більше пробілів, після яких йде ще одна відкриваюча квадратна дужка, наприклад [[
, [=[
або [=====[
.
Якщо текстовий рядок почався із довгої відкриваючої дужки, то він має закінчуватись відповідною довгою закриваючою дужкою, наприклад ]]
, ]=]
або ]=====]
..
Якщо після довгої відкриваючої дужки одразу йде зміна рядка, то ця зміна рядка не включається до текстового рядка. Якщо ж зміна рядка йде одразу перед довгою закриваючою дужкою, то зміна рядка включається до текстового рядка.
В текстових рядках на кінцях яких стоять довгі дужки, на відміну від лапок, не інтерпретуються керуючі послідовності.
-- Цей довгий текстовий рядок
foo = [[
bar\tbaz
]]
-- є еквівалентним до цього текстового рядка, на кінцях якого стоять лапки
foo = 'bar\\tbaz\n'
Зверніть увагу що всі текстові рядки вважаються правдивими якщо їх перевести в логічне значення, на відміну від більшості інших мов програмування, де порожній текстовий рядок вважається неправдивим.
Числа
В Lua є тільки один числовий тип, який внутрішньо представлений числом з рухомою десятичною точкою із подвійною точністю. В цьому форматі цілі числа від -9007199254740991
(-253 + 1) до 9007199254740991
(253 - 1) представлені точно, але числа поза цим діапазоном та дробові числа можуть бути викривлені через помилки округлення.
Числові значення можуть бути задані використовуючи точку (.
) в якості розділового знаку між цілою та дробною частинами, наприклад 123456.78
. Також числові значення можна задати використовуючи експоненціальний запис без пробілів, наприклад 1.23e-10
, 123.45e20
або 1.23E5
. Цілі значення можна також задати в шістнадцятковій системі числення використовуючи префікс 0x
, наприклад 0x3A
.
Numbers may also be represented using E notation without spaces, e.g. 1.23e-10
, 123.45e20
, or 1.23E+5
.
Integers may also be specified in hexadecimal notation using a 0x
prefix, e.g. 0x3A
.
Значення NaN разом із негативною та позитивною нескінченностями коректно зберігаються та обробляються. Константа math.huge
дорівнює позитивній нескінченності, яка також може бути отримана за допомогою 1/0
, а за допомогою 0/0
можна отримати значення NaN.
Зверніть увагу, що всі числа вважаються правдивими якщо їх перевести в логічне значення, на відміну від більшості інших мов програмування, де 0 вважається неправдивим. Якщо переводити число в текстовий рядок, то всі кінцеві числа переводяться в їх десяткове представлення, можливо із використанням експоненціального запису, NaN переводиться в «nan»
або «-nan»
, нескінченності переводяться в «inf»
або «-inf»
.
Known bug: the Lua interpreter will treat all instances of 0
and -0
as whichever of the two is encountered first when the script is compiled, which means that the return values of tostring(0)
, 1/-0
(and so on) are affected by where they occur in the code.
This can cause unexpected results, particularly if all instances of 0
are converted to "-0"
on return.
If necessary, this can be circumvented by generating zero values using tonumber("0")
and tonumber("-0")
, which doesn't seem to cause or be affected by the issue. See [1].
Таблиці
Таблиці в Lua є асоціативними масивами (хешами) подібно до об'єктів в JavaScript та масивів в PHP.
Таблиці задаються за допомогою фігурних дужок. Порожню таблицю можна задати за допомогою коду {}
. Щоб задати поля таблиці при її створенні, треба їх записати всередині фігурних дужок розділяючи їх комами або крапками з комами. Це можна зробити такими способами:
- *
[вираз1] = вираз2
використовує (перше або єдине) значення «вираз1» як ключ та (перше або єдине) значення «вираз2» як значення. назва = вираз
є еквівалентним до[«назва»] = вираз
.вираз
є еквівалентним до[i] = вираз
, де «і» це ціле число яке починається з 1 та збільшується із кожним значенням заданим цим способом. Якщо це останнє поле таблиці та вираз має багато значень, то всі вони включаються до таблиці. В інакшому випадку включається тільки перше значення виразу.name = expression
is equivalent to["name"] = expression
expression
is roughly equivalent to[i] = expression
, where i is an integer starting at 1 and incrementing with each field specification of this form. If this is the last field specifier and the expression has multiple values, all values are used; otherwise only the first is kept.
Доступ до полів таблиці можна отримати за допомогою синтаксису квадратних дужок, наприклад table[key]
. Якщо ключ є текстовим рядком який відповідає критеріям назви, то значення також можна отримати через синтаксис точки, наприклад table.key
, що є еквівалентним до table['key']
. Виклик функції, яка є значенням в таблиці, можна виконати за допомогою синтаксису двокрапки, наприклад table:func( ... )
, що є еквівалентним до table['func']( table, ... )
або table.func( table, ... )
.
Послідовністю називають таблицю в якій задані значення (не nil) для всіх цілих чисел від 1 до N, а значення для чисел більших за N не задані або дорівнюють nil. Багато функцій Lua працює тільки із послідовностями та ігнорує ключі в таблицях, які не є додатними цілими числами.
На відміну від більшості інших мов програмування, будь-яке значення окрім nil та NaN може бути використане як ключ таблиці. Значення не змінюють свій тип при використанні їх в якості ключів. Всі перелічені нижче способи задання значень в таблиці є правильними:
-- Створення таблиці
t = {}
t["foo"] = "foo"
t.bar = "bar"
t[1] = «один»
t[2] = «два»
t[3] = «три»
t[12] = «число дванадцять»
t["12"] = «струна дванадцять»
t[true] = "true"
t[tonumber] = «так, навіть функції можуть бути клавішами таблиці»
t[t] = «так, таблиця також може бути ключем таблиці. Навіть сам по собі.»
-- Тут створюється таблиця така сама як і попередня
t2 = {
foo = "foo",
bar = "bar",
«один»,
«два»,
[12] = «число дванадцять»,
["12"] = «струна дванадцять»,
«три»,
[true] = "true",
[tonumber] = "yes, even functions may be table keys",
}
t2[t2] = "yes, a table may be a table key too. Even in itself."
Подібно до ключів, будь-яке значення окрім nil може зберігатись в таблиці як значення. Присвоєння ключу таблиці значення nil еквівалентне видаленню цього ключа з таблиці. Також спроба звернутися до значення ключа, якому не було присвоєне значення, повертає nil.
Зверніть увагу, що в мові Lua не відбувається неявне копіювання таблиць. Якщо таблиця передається функції як аргумент і функція змінює цю таблицю, то зміни залишаються навіть після завершення роботи функції.
Якщо перевести таблицю в текстовий рядок, то результатом буде «table», хоча це може бути змінене перевизначенням метаметоду __tostring
. Навіть порожня таблиця при переведенні в логічне значення вважається правдивою.
Функції
Функції в Lua є повноправними значеннями. Їх можна створювати анонімними, передавати як аргументи, присвоювати змінним і так далі.
Функції створюються за допомогою ключового слова function
та викликаються за допомогою назви і дужок в кінці неї. Синтаксичний цукор доступний для іменованих функцій, локальних функцій та функцій які є значеннями в таблиці. Дивіться розділи «Оголошення функції» та «Виклик функцій» нижче.
Функції в Lua є замиканнями. Це означає що вони містять посилання на область видимості в якій вони були оголошені та можуть отримувати доступ і змінювати змінні в цій області видимості.
Подібно до таблиць, якщо функція присвоюється іншій змінній або передається іншій функції, то копія функції не створюється, а використовується той самий «об'єкт» функції.
Якщо перевести функцію в текстовий рядок, то результатом буде «function».
Типи, що не підтримуються
Тип даних «користувацькі дані» використовується щоб зберігати інформацію для розширень до Lua написаних на інших мовах програмування, наприклад цей тип даних може використовуватись щоб зберігати вказівник чи структуру з мови C. Розширення Scribunto використовується в середовищі, яке не дозволяє використання компільованого коду, тому в цьому типі даних немає потреби.
Тип даних «поток» призначений для паралельних обчислень, які не підтримуються в Scribunto.
return p
There is a strict limit of max 60 unique upvalues acessed inside a function. An upvalue is a value declared outside of a function and used inside it. As upvalues do count:
- variables (a table with many elements counts as one upvalue)
- functions (only those directly called from function in question, not their dependencies)
A violation of the limit can be triggered by a use of such a variable or function, not by its mere presence or availability. Repeated access to same upvalue does not exhaust the limit further.
Метатаблиці
Кожна таблиця може мати асоційовану з нею іншу таблицю яку називають «метатаблиця». Поля в метатаблицях використовуються деякими операторами і функціями та визначають поведінку таблиці, яка може відрізнятись від такої в інших таблиць. Метатаблиця певної таблиці може бути отримана за допомогою функції getmetatable(), а встановлена за допомогою функції setmetatable().
При зверненні до метафункцій метатаблиці, вони повертаються так, ніби до них звернулись за допомогою функції rawget().
Поля метатаблиці, які впливають на саму таблицю:
- __index
- Використовується коли звернення до поля таблиці
t[key]
повертає nil. Якщо значенням поля таблиці є інша таблиця, то буде повернуте значення цієї іншої таблиці за тим cамим ключем, тобто__index[key]
(що може включати поле __index метатаблиці цієї таблиці). Якщо значенням поля таблиці є функція, вона буде викликана як через__index( t, key )
. Функція rawget() дозволяє обійти цей метаметод. - __newindex
- Використовується при присвоєнні значення ключу таблиці (
t[key] = value
) коли$rawget(t, key)
повернуло би nil. Якщо значенням поля таблиці є інша таблиця, то присвоєння повториться і в цій іншій таблиці, тобто__newindex[key] = value
(що може включати поле __newindex метатаблиці цієї таблиці). Якщо значенням поля є функція, то вона буде викликана як через__newindex(t, key, value)
. Функція rawset() дозволяє обійти цей метаметод. - __call
- Використовується коли до таблиці звертаються як до функції (
t(···)
). Значенням поля __call має бути функція, яка викликається як через__call(t, ···)
. - __mode
- Використовується щоб створювати таблиці із слабкими посиланнями (такими, які ігноруються збирачем сміття). Значенням цього поля має бути текстовий рядок. За замовчуванням, жодне значення, яке використовується в таблиці як ключ або значення, не буде видалене збирачем сміття. Якщо текстовий рядок, який є значенням поля __mode, містить літеру «k», то ключі таблиці можуть бути видалені якщо в таблиці немає сильних посилань. Якщо текстовий рядок містить літеру «v», то те саме відбувається із значеннями. В обох випадках з таблиці видаляються ключ і значення, яке йому відповідає. Зверніть увагу, що ця поведінка стає невизначеною, якщо це поле змінюється після того, як таблиця була використана як метатаблиця.
Іншими полями метатаблиць є:
Зверніть увагу, що в Lua всі текстові рядки мають спільну метатаблицю, в якій __index
посилається на таблицю string
. Ця метатаблиця недоступна в Scribunto, так само як і таблиця string. Таблиця string, яка доступна в модулях, є лише копією оригінальної таблиці.
Змінні
Змінною є область пам'яті де зберігається значення. В Lua існує три типи змінних: глобальні змінні, локальні змінні та поля таблиці.
Глобальні та локальні змінні представлені назвами (так само як і аргументи функції, які є одним із видів локальних змінних). Змінні вважаються глобальними якщо прямо не вказано що вони локальні використанням ключового слова local
. Будь-яка змінна, якій не присвоєно значення, вважається рівною nil.
Глобальні змінні зберігаються в стандартній таблиці Lua під назвою «environment». Ця таблиця також часто доступна як глобальна змінна _G
. Можна встановити метатаблицю для цієї таблиці. Тоді метаметоди __index та __newindex будуть викликатися при кожному зверненні і зміненні глобальної змінної, так само як і для полів будь-якої таблиці.
Оточення функції може бути отримане за допомогою функції getfenv() та змінене за допомогою setfenv(). В Scribunto ці функції є значно обмеженими якщо вони взагалі доступні.
Локальні змінні мають власні області видимості. Дивіться Оголошення локальних змінних.
Вирази
Виразом є щось, що містить значення: літерали (числа, текстові рядки, true, false, nil), оголошення анонімних функцій, конструктори таблиць, посилання на змінні, виклики функцій, вираз для змінної кількості аргументів, вирази в дужках, унарні оператори застосовані до виразів та вирази поєднані із бінарними операторами.
Більшість виразів має лише одне значення. Виклики функцій та вирази для змінної кількості аргументів можуть мати будь-яку кількість значень. Зверніть увагу, що розміщення виклику функції або виразу для змінної кількості аргументів всередині дужок відкидає всі значення крім першого.
Списком виразів є список виразів розділений комами. Всі вирази в списку, окрім останнього, можуть мати лише одне значення, тобто всі інші значення відкидаються або вираз дорівнює nil якщо значень немає. Всі значення останнього виразу в списку стають значеннями списку виразів.
Арифметичні оператори
Lua підтримує звичайні математичні оператори: додавання, віднімання, множення, ділення, остача від ділення, зведення до степені та унарний мінус.
Коли всі операнди є числами або текстовими рядками, які функція tonumber() може перетворити на числа, оператори матимуть своє звичайне математичне значення.
Якщо хоч один операнд є таблицею із відповідним метаметодом, то викликається цей метаметод.
Оператор | Дія | Приклад | Метаметод | Примітки |
---|---|---|---|---|
+ | Додавання | a + b | __add | |
- | Віднімання | a - b | __sub | |
* | Множення | a * b | __mul | |
/ | Ділення | a / b | __div | Ділення на нуль не є помилкою, його результатом буде NaN або нескінченність. |
% | Остача від ділення | a % b | __mod | Задане як a % b == a - math.floor( a / b ) * b
|
^ | Зведення до степені | a ^ b | __pow | Степінь не обов'язково має бути цілим числом. |
- | Унарний мінус | -a | __unm |
Оператори відношення
Операторами відношення в Lua є ==
, ~=
, <
, >
, <=
та >=
. Результатом, який повертає оператор відношення, завжди є логічне значення.
Оператор рівності (==
) спершу порівнює типи свої операндів. Якщо вони різні, то повертається false. Якщо ні, то далі порівнюються значення. Функції вважаються рівними тільки якщо вони відсилаються до одного і того самого об'єкта функції. Наприклад function() end == function() end
поверне false, оскільки порівнюються дві різні анонімні функції. Таблиці за замовчуванням порівнюються в той самий спосіб, але це можна змінити за допомогою метаметоду __eq.
Оператор нерівності (~=
) є просто логічним запереченням до рівності.
Для операторів порядку якщо обидва операнди є числами або строками, вони порівнюються напряму. Якщо ні, то використовуються такі метаметоди:
a < b
використовує__lt
.a <= b
використовує__le
якщо він існує, або__lt
якщо він існує (тоді вираз вважається рівнимnot (b < a)
).a > b
вважається рівнимb < a
a >= b
вважається рівнимb <= a
Якщо потрібні метаметоди не існують, то виникає помилка.
Логічні оператори
Логічними операторами є and
, or
та not
. Всі вони використовують стандартну інтерпретацію, в якій nil та false вважаються неправдивими, а все інше правдивим.
Оператор and
спочатку дивиться на лівий операнд. Якщо він є неправдивим, то оператор повертає false і другий операнд не обчислюється. В іншому випадку повертається значення другого операнда.
Оператор or
теж спочатку дивиться на лівий операнд. Якщо він є правдивим, то оператор повертає true і другий операнд не обчислюється. В іншому випадку повертається значення другого операнда.
Оператор not
повертає протилежне значення до значення свого операнда.
Зверніть увагу, що оператори and
та or
є скороченими. Наприклад, код foo() or bar()
викличе функцію bar()
тільки якщо foo()
поверне неправдиве значення.
Оператор об'єднання текстових рядків
Оператор об'єднання текстових рядків представлений двома точками і має вигляд a .. b
. Якщо обидва оператори є числами, то вони перетворюються на текстові рядки та об'єднуються. Якщо оператори не є ні текстовими рядками, ні числами, то для них викликається метаметод __concat. Якщо він не існує, то виникає помилка.
Зверніть увагу, що текстові рядки в Lua є незмінними, тому цикл, на кожній ітерації якого відбувається об'єднання текстових рядків a = a .. b
, буде створювати новий текстовий рядок на кожній ітерації, а попередні рядки будуть видалені збирачем сміття. Якщо потрібно об'єднати одразу багато текстових рядків, то краще скористатися методом string.format() або створити послідовність з текстових рядків та викликати метод table.concat() для неї.
Оператор довжини
Оператор довжини представлений символом #
і використовується в вигляді #a
. Якщо a
є текстовим рядком, то оператор повертає його довжину в байтах. Якщо a
є послідовністю, то оператор повертає кількість полів в ній.
Якщо a
є таблицею, але не послідовністю, то оператор може повернути будь-яке N >= 1 таке, що a[N]
не дорівнює nil, а a[N+1]
дорівнює nil, починаючи з N = 1, навіть якщо існують поля з більшим ключем, значення яких не дорівнює nil. Наприклад:
-- Це не є послідовністю, оскільки a[3] дорівнює nil, але a[4] ні.
a = { 1, 2, nil, 4 }
-- Подальший код може повернути 2 або 4.
-- Результат може відрізнятися навіть якщо сама таблиця не змінювалась.
mw.log( #a )
Пріоритети операторів
Пріоритети операцій або черговість операцій в Lua від найвищого до найнижчого:
^
not
#
-
унарний мінус*
/
%
+
-
віднімання..
<
>
<=
>=
~=
==
and
or
Всередині рівнів пріоритетності більшість бінарних операторів є ліво-асоціативними, тобто a / b / c
трактується як (a / b) / c
. Зведення до степені та об'єднання текстових рядків є право-асоціативними, тобто a ^ b ^ c
трактується як a ^ (b ^ c)
.
Виклик функції
Виклик функції в Lua виглядає так само, як і в більшості інших мов програмування, а саме назва функції після якої йде список параметрів в дужках.
func( список параметрів )
Аргументи функції є списком виразів, тому тільки останній вираз може мати більше одного значення.
Якщо функція викликається із меншою кількістю параметрів, ніж це зазначено в оголошенні функції, то зайві аргументи приймають значення nil. Якщо функція викликається із більшою кількістю параметрів, ніж зазначено в оголошенні, то зайві параметри відкидаються. Також функція може приймати змінну кількість аргументів, дивіться Оголошення функції.
Lua також дозволяє пряме звернення до значення, яке повертає функція, за допомогою синтаксису func()()
. Якщо функція повертає вираз, який є складнішим за звернення до однієї змінної, то замість змінної можна написати вираз в дужках.
В Lua є синтаксичний цукор виклику функції для двох загальних випадків. Перший випадок коли таблиця використовується як об'єкт, а функція, яку треба викликати, є методом об'єкту. Синтаксис
table:name( список параметрів )
еквівалентним до
table.name( table, список параметрів )
Другий випадок є методом імплементації іменованих аргументів передачею до функції таблиці, яка містить поля назва-значення. В випадку якщо до функції передається лише один аргумент, дужки можна не писати. Наприклад, виклики функцій
func{ arg1 = exp, arg2 = exp } func"string"
є еквівалентними до
func( { arg1 = exp, arg2 = exp } ) func( "string" )
Ці способи можна поєднувати. Наступні виклики функцій є еквівалентними
table:name{ arg1 = exp, arg2 = exp } table.name( table, { arg1 = exp, arg2 = exp } )
Оголошення функції
Синтаксис оголошення функції виглядає так:
function nameoptional ( var-listoptional )
блок
end
Всі змінні в var-list є локальними змінними функції і вони отримують значення зі списку аргументів при виклику функції. Додаткові локальні змінні можна оголосити всередині блоку функції.
Коли викликається функція, код всередині блоку функції виконується тільки після того, як всі локальні змінні з var-list створені та отримали значення. Якщо досягнуто виразу із твердженням return, то виконання коду функції зупиняється і вираз виклику функції приймає значення повернуте твердженням return. Якщо виконання коду функції доходить до кінця блоку, жодного разу не зустрівши твердження return, то вираз виклику функції має нуль значень.
Функції в Lua є замиканнями. Загальною практикою є оголошення «приватних статичних» змінних як локальних в області видимості, де оголошується функція. Наприклад
-- Ця функція повертає іншу функцію, яка додає число до свого аргумента.
function makeAdder( n )
return function( x )
-- The variable n from the outer scope is available here to be added to x
return x + n
end
end
local add5 = makeAdder( 5 )
mw.log( add5( 6 ) )
-- Виводить 11.
Функцію можна оголосити так, щоб вона приймала змінну кількість аргументів, за допомогою виразу ...
, який має бути останнім в списку аргументів.
Всередині блоку коду функції можна використовувати вираз ...
, який повертатиме список всіх додаткових аргументів, переданих при виклику функції. Наприклад
local join = function ( separator, ... )
-- get the extra arguments as a new table
local args = { ... }
-- get the count of extra arguments, correctly
local n = select( '#', ... )
return table.concat( args, separator, 1, n )
end
join( ', ', 'foo', 'bar', 'baz' )
-- Повертає текстовий рядок «foo, bar, baz».
Функція select() працює із списками значень. Зокрема код select(«#», ...)
має використовуватись замість #{ ... }
для отримання кількості значень в списку, оскільки { ... }
може не бути послідовністю.
В Lua є синтаксичний цукор для поєднання оголошення функції з її присвоєнням змінній. Дивіться Твердження оголошення функції.
Зверніть увагу, що такий код не працюватиме:
local factorial = function ( n )
if n <= 2 then
return n
else
return n * factorial( n - 1 )
end
end
Оскільки оголошення функції обробляється до присвоєння значення локальній змінній, «factorial» всередині тіла функції буде невизначеним. Цієї проблеми можна уникнути спочатку оголосивши локальну змінну, а в наступному твердженні присвоївши їй функцію або іншим методом описаним в розділі Твердження оголошення функції.
Твердження
Твердженням є основна одиниця виконання: одне присвоєння, контрольна структура, виклик функції, оголошення змінної, тощо.
Чанком є послідовність тверджень, розділених крапками з комами (необов'язково). Тіло анонімної функції є чанком, тому там можна оголошувати локальні змінні, отримувати аргументи та повертати значення.
Блоком це теж послідовність тверджень, як і чанк. Блок можна явно визначити за допомогою синтаксису do block end
. Це використовується для обмеження області видимості локальних змінних або щоб вставити твердження return
чи break
всередину іншого блоку.
Присвоєння
список змінних = список виразів
Список змінних є списком змінних, які розділених комами. Аналогічно список виразів. Всі вирази обчислюються до присвоєння, тому код a, b = b, a
поміняє значення змінних a та b місцями.
Оголошення локальної змінної
local список змінних
local список змінних = список виразів
Локальні змінні можна оголошувати будь-де всередині блоку або чанку. Перша форма оголошення, показана вище, просто оголошує змінні, але не присвоює їм значення, тому вони матимуть значення nil. Друга форма одразу після оголошення присвоює змінним значення так само, як описано вище в розділі Присвоєння вище.
Зверніть увагу що видимість локальної змінної починається із наступного твердження, після її оголошення. Тому код local x = x
оголошує локальну змінну x та присвоює їй значення глобальної змінної x. Область видимості локальної змінної продовжується до кінця найвнутрішнього блоку, в якому вона була оголошена.
Контрольні структури
while exp do блок end
Твердження while виконує блок коду знову і знову, поки значення виразу залишається правдивим.
repeat блок until exp
Твердження repeat виконує блок коду знову і знову, поки значення виразу не стане правдивим. Локальні змінні оголошені всередині блока доступні і в виразі.
for name = exp1, exp2, exp3 do блок end
for name = exp1, exp2 do блок end
Перша форма циклу for оголошує локальну змінну, присвоює їй значення exp1 та повторює блок доки ця змінна не стане рівною чи більшою за exp2, на кожній ітерації збільшуючи змінну на exp3. Якщо вираз exp3 пропущено, то він вважається рівним 1. Всі вирази обчислюються один раз до початку виконання блоку коду.
Форма циклу for, яка показана вище, є еквівалентною до
do
local var, limit, step = tonumber( exp1 ), tonumber( exp2 ), tonumber( exp3 )
if not ( var and limit and step ) then
error()
end
while ( step > 0 and var <= limit ) or ( step <= 0 and var >= limit ) do
local name = var
block
var = var + step
end
end
окрім того, що змінні var, limit та step більше ніде не доступні. Зверніть увагу, що змінна name є локальною для цього блоку, тому щоб використовувати її значення після циклу, це значення треба скопіювати в змінну оголошену поза циклом.
for список змінних in список виразів do блок end
Друга форма циклу for працює із функцією-ітератором. Як і в першій формі, всі вирази обчислюються один раз до початку виконання блоку коду.
Фома циклу for вказана вище є еквівалентною до
do
local func, static, var = expression-list
while true do
local var-list = func( static, var )
var = var1 -- ''var1'' is the first variable in ''var-list''
if var == nil then
break
end
block
end
end
окрім того, що знов ж таки змінні func, static та var більше ніде не доступні. Зверніть увагу, що змінні в var-list є локальними для цього блоку, тому щоб використовувати їх значення після циклу, ці значення треба скопіювати в змінні оголошені поза циклом.
Часто список виразів заміняють функцією, яка повертає три значення. Якщо можна написати ітератор так, щоб він залежав тільки від переданих йому аргументів, то краще так і зробити. В інакшому випадку Інструкція з програмування на Lua рекомендує використовувати замикання, яке буде змінювати значенням на кожній ітерації замість таблиці.
if exp1 then блок1 elseif exp2 then блок2 else блок3 end
Виконує блок1 якщо вираз exp1 є правдивим, інакше якщо вираз exp2 є правдивим виконує блок2. Якщо ні exp1, ні exp2 не є правдивими, то виконується блок3. else блок3
можна пропустити, а elseif exp2 then блок2
можна повторити стільки разів, скільки потрібно, чи теж пропустити.
return список виразів
Твердження return використовується щоб повертати значення з функцій або чанків. Список виразів є списком виразів, які розділені комами. Він може складатися з нуля чи більше виразів.
В Lua підтримується хвостова рекурсія. Якщо список виразів
містить лише один вираз, який є викликом функції, то поточний стековий фрейм буде використаний ще раз щоб викликати цю функцію. Це впливає на функції, які мають справу із викликом стеку, наприклад getfenv()
або debug.traceback()
.
Твердження return має бути останнім твердженням блоку. Якщо необхідно повернути значення всередині блоку, то це можна зробити за допомогою вкладеного блоку do return end
.
break
Твердження break використовується для переривання виконання циклів while, repeat або for. Воно переводить виконання програми на твердження наступне після циклу.
Твердження break має бути останнім твердженням блоку. Якщо необхідно припинити виконання всередині блоку, то це можна зробити за допомогою вкладеного блоку do break end
.
Unlike some other languages, Lua does not have a "continue" statement for loops (i.e. a statement to move onto the next iteration without breaking the loop altogether).
It is straightforward to achieve the same effect by nesting a repeat ... until true
block immediately inside the main loop, which will only ever iterate once for each iteration of the main loop (as its condition is always true).
Using break
will only end the inner loop, which has the practical effect of causing the main loop to continue onto the next iteration.
If it is necessary to use break
on the main loop, simply declare a variable which is checked each time the inner loop completes, and set it when necessary.
Виклик функції як твердження
Виклик функції може бути використаний як твердження. В такому випадку функція викликається тільки щоб виконати якісь дії, а всі значення які вона повертає відкидаються (наприклад функція mw.log() використовується для виводу повідомлень при налагодженні, а значення які вона повертає, частіше за все відкидаються).
Твердження оголошення функції
В Lua підтримується синтаксичний цукор, який робить оголошення функції та присвоєння її змінній простішим. Такі пари оголошень функцій є еквівалентними:
-- Basic declaration function func( var-list ) блок end func = function ( var-list ) блок end
-- Local function local function func( var-list ) блок end local func; func = function ( var-list ) блок end
-- Function as a field in a table function table.func( var-list ) блок end table.func = function ( var-list ) блок end
-- Function as a method in a table function table:func( var-list ) блок end table.func = function ( self, var-list ) блок end
Зверніть увагу, що оголошення функції з використанням синтаксису двокрапки є аналогічним до такого з використанням точки, окрім того що в першому випадку до функції першим аргументом self
треба передавати таблицю, в якій вона знаходиться.
Обробка помилок
Помилки можна згенерувати за допомогою функцій error() та assert(). Функції pcall() та xpcall() дозволяють обробляти помилки. Зверніть увагу, що деякі внутрішні помилки Scribunto неможливо обробити в колі Lua.
Збирання сміття
В Lua реалізоване автоматичне керування пам'яттю. Це означає що вам не потрібно резервувати пам'ять для нових об'єктів або звільняти її коли ці об'єкти більше не потрібні. Lua керує пам'яттю за допомогою збирача сміття, який час від часу видаляє всі об'єкти, на які більше немає посилань або є тільки слабкі посилання. Будь-яка пам'ять яка використовується в Lua є об'єктом автоматичного керування: таблиці, функції, текстові рядки, тощо.
Збирання сміття відбувається автоматично і його не можна змінювати в Scribunto.
Стандартні бібліотеки
Стандартні бібліотеки Lua реалізують основні можливості та функції необхідні для нормального функціонування мови. В Scribunto підтримується тільки частина стандартних бібліотек.
Основні функції
_G
Глобальні змінні містять посилання на поточну таблицю глобальних змінних, наприклад змінна foo
може бути також отримана через _G.foo
. Зверніть увагу, що сама таблиця _G не є якоюсь особливою, над нею можна виконувати всі дії, які можна виконувати над будь-якою іншою таблицею.
foo = 1
mw.log( foo ) -- журнали «1»
_G.foo = 2
mw.log( foo ) -- журнали «2»
_G = {} -- _G no longer points to the global variable table
_G.foo = 3
mw.log( foo ) -- still logs "2"
Таблицю глобальних змінних можна використовувати так само як будь-яку іншу таблицю. Наприклад
-- Call a function whose name is stored in a variable
_G[var]()
-- Log the names and stringified values of all global variables
for k, v in pairs( _G ) do
mw.log( k, v )
end
-- Log the creation of new global variables
setmetatable( _G, {
__newindex = function ( t, k, v )
mw.log( "Creation of new global variable '" .. k .. "'" )
rawset( t, k, v )
end
} )
_VERSION
Текстовий рядок, який містить назву поточної версії Lua, наприклад «Lua 5.1».
assert
assert( v, message, ... )
Якщо v
дорівнює nil або false, то виникає помилка. В такому випадку message
використовується як текст повідомлення про помилку. Якщо воно дорівнює nil або не задане, то текстом повідомлення про помилку стає «assertion failed!». Якщо воно є текстовим рядком або числом, то використовується це значення, в інакшому випадку виникає ще одна помилка.
Якщо v
дорівнює будь-якому іншому значенню, то функція повертає всі свої аргументи, включаючи v
та message
.
В Lua є загальною практикою для функцій повертати true в випадку нормального виконання або повертати nil чи false разом із повідомленням про помилку у випадку виникнення помилки під час виконання. Функція дозволяє реалізувати перевірку на помилки. Щоб перевірити чи нормально виконалась функція, виклик цієї функції треба зробити першим аргументом функції assert
, наприклад:
-- This doesn't check for errors
local result1, result2, etc = func( ... )
-- This works the same, but does check for errors
local result1, result2, etc = assert( func( ... ) )
error
error( message, level )
Генерує помилку, текстом повідомлення про яку є аргумент message
.
Функція error
зазвичай додає інформацію про місце помилки. Аргумент level
означає рівень вкладеності помилки. Якщо він дорівнює 1 або пропущений, то надається інформація про місце самої помилки. Якщо він рівний 2, то місце виклику функції, в якій виникла помилка. Якщо він рівний 3, то місце виклику функції, в якій викликається функція, в якій виникла помилка, і так далі. Якщо цей аргумент дорівнює 0, то інформація про місце помилки не надається.
getfenv
getfenv( f )
Зверніть увагу, що ця функція може бути недоступною у деяких проєктах, в залежності від значення allowEnvFuncs
в їх налаштуваннях.
Повертає оточення (таблицю глобальних змінних) в залежності від аргументу f
:
- Якщо 1, nil або пропущений, то повертає оточення для функції, яка викликає
getfenv
. Часто, це буде те саме, що і звернення до _G. - Якщо ціле число від 2 до 10, то повертає оточення функції відповідного рівня з стеку викликів функції. Наприклад, при значенні 2 функція поверне оточення для функції, в якій була викликана функція, в якій була викликана
getfenv
, і так далі. Якщо цей аргумент буде більшим за кількість викликів функцій в стеку або функція потрібного рівня буде мати хвостову рекурсію, то виникне помилка. - Якщо аргументом є функція, то буде повернуте оточення, яке буде використане при виклику цієї функції.
Оточення, які використовуються всіма стандартними бібліотечними функціями та функціями бібліотеки Scribunto, є захищеними. При спробі отримати доступ до цих оточень функція getfenv
поверне nil.
getmetatable
getmetatable( table )
Повертає метатаблицю для таблиці вказаної як аргумент. Якщо переданий аргумент не є таблицею, то функція поверне nil.
Якщо метатаблиця має поле __metatable
, то буде повернуте саме воно а не сама метатаблиця.
ipairs
ipairs( t )
Повертає три значення: функцію-ітератор, таблицю t
та 0. Це потрібно для використання ітеративної форми циклу for
:
for i, v in ipairs( t ) do
-- process each index-value pair
end
В цьому циклі будуть оброблені всі пари (1, t[1]), (2, t[2]) і так далі поки t[i] не буде дорівнювати nil.
Стандартна поведінка може бути змінена якщо задати метаметод __ipairs
. Якщо цей метаметод існує, то функція поверне три значення, які повертає метаметод __ipairs( t )
.
next
next( table, key )
Ця функція дозволяє обійти в циклі всі ключі таблиці. Якщо key
дорівнює nil або пропущений, то повертається перший ключ в таблиці та його значення. В іншому випадку повертається наступний ключ та його значення. Коли ключів більше не залишилось, то повертається nil. Є можливість перевірити чи є таблиця порожньою за допомогою виразу next( t ) == nil
.
Зверніть увагу, що порядок в якому повертаються ключі є випадковим, навіть для таблиць з цілочисельними ключами. Щоб обійти всі ключі в порядку зростання, використовуйте звичайну форму циклу for або функцію ipairs.
Поведінка функції next
для випадків коли під час циклу створюється новий ключ, є невизначеною.
pairs
pairs( t )
Повертає три значення: функцію-ітератор (next або подібну), таблицю t
та nil (функція ipairs
повертає те саме, окрім 0 замість nil). Це потрібно для використання ітеративної форми циклу for
:
for k, v in pairs( t ) do
-- process each key-value pair
end
Обійде всі пари ключ-значення в таблиці t
так само як би це зробила функція next; дивіться документацію для next щодо обмежень щодо зміни таблиці під час обходу.
Стандартна поведінка функції може бути змінена створенням метаметоду __pairs. Якщо цей метод існує, то функція поверне три значення, які повертає метаметод __pairs( t )
.
pcall
pcall( f, ... )
Викликає функцію f
із вказаними аргументами в «безпечному режимі». Це означає, що якщо під час виконання функції f
виникне помилка, то pcall
поверне false та текст повідомлення про помилку. Якщо помилок не виникне, то функція поверне true та всі значення повернуті функцією f
.
На псевдокоді функція pcall
виглядає приблизно так:
function pcall( f, ... )
try
return true, f( ... )
catch ( message )
return false, message
end
end
rawequal
rawequal( a, b )
Ця функція еквівалентна до a == b
, окрім того, що вона ігнорує метаметоди __eq обох аргументів.
rawget
rawget( table, k )
Ця функція еквівалентна до table[k]
, окрім того, що вона ігнорує метаметод __index таблиці.
rawset
rawset( table, k, v )
Ця функція еквівалентна до table[k] = v
, окрім того, що вона ігнорує метаметод __newindex таблиці.
select
select( index, ... )
Якщо index
є цілим числом, то функція повертає всі аргументи ...
після цього індексу. Якщо index
є текстовим рядком «#», то функція повертає кількість аргументів в ...
.
If index
is the string "#"
, returns the number of arguments in ...
.
Note: unlike tables, lists of arguments (including the vararg expression ...
) treat nil
as a distinct value (see documentation for # and unpack for the problem with nil
in tables). For example:
select(2, "foo", "bar")
returns"bar"
.select(2, "foo", nil, "bar", nil)
returnsnil, "bar", nil
.select("#", "foo", "bar")
returns2
.select("#", "foo", "bar", nil)
returns3
.
Іншими словами, функція select
є подібною до коду нижче, окрім того що функція коректно працює навіть коли nil
містить значення nil (дивіться документацію для # та unpack для інформації про проблеми із значеннями nil).
function select( index, ... )
local t = { ... }
local maxindex = table.maxn( t )
if index == "#" then
return maxindex
else
return unpack( t, index, maxindex )
end
end
setmetatable
setmetatable( table, metatable )
Встановлює метатаблицю для вказаної таблиці. Аргумент metatable
може дорівнювати nil, але все одно має бути вказаний.
Якщо поточна метатаблиця має поле setmetatable
, то виникне помилка.
tonumber
tonumber( value, base )
Перетворює аргумент value
в число в системі числення вказаній в аргументі система числення
. Якщо tonumber
є числом або текстовим рядком який можна перетворити на число, то повертається це число, в інакшому випадку повертається nil.
Необов'язковий аргумент base
(за замовчуванням 10) визначає систему числення, в якій треба повернути число. Він може мати цілочисельне значення від 2 до 36 включно. Якщо система числення є більшою за 10, то літера «A» (моде бути і великою, і маленькою) представляє цифру 10, «B» представляє цифру 11, і так далі до літери «Z» яка представляє 35.
Для системи числення 10, аргумент значення
може мати дробову частину, може бути вираженим за допомогою експоненціального запису або мати «0x» на початку, що вказує на систему числення 16. Для інших систем числення можна вказувати лише невід'ємні цілі числа.
tostring
tostring( value )
Перетворює value
на текстовий рядок. Дивіться розділ Типи даних для інформації про те яким чином перетворюється на текстовий рядок кожен тип даних.
Стандартна поведінка функції для таблиць може бути змінена створенням метаметоду __tostring. Якщо цей метод існує, то функція поверне значення, яке повертає метаметод __tostring( value )
.
type
type( value )
Повертає тип даних який має value
в вигляді текстового рядку: "nil"
, "number"
, "string"
, "boolean"
, "table"
або "function"
.
unpack
unpack( table, i, j )
Повертає значення із вказаної таблиці так само, як код виду table[i], table[i+1], ···, table[j]
. Якщо нуль або не вказано, i
за замовчуванням дорівнює 1, а j
– #table
.
If the table does not have a value for a particular key, unpack will return nil for that value. For example, unpack({"foo", [3] = "bar"}, 1, 4)
returns "foo", nil, "bar", nil
.
Зверніть увагу, що результат не визначений якщо table
не є послідовністю і одночасно j
дорівнює nil або пропущене. Дивіться розділ Оператор довжини.
xpcall
xpcall( f, errhandler )
Працює так само як і функція pcall
, окрім того що повідомлення про помилку передається до функції errhandler
перед поверненням.
На псевдокоді функція xpcall
виглядає приблизно так:
function xpcall( f, errhandler )
try
return true, f()
catch ( message )
message = errhandler( message )
return false, message
end
end
Бібліотека debug (бібліотека налагодження)
debug.traceback
debug.traceback(повідомлення, рівень)
Повертає текстовий рядок з відстеженням стеку викликів функцій. Необов'язковий аргумент повідомлення
вставляється на початок цього текстового рядка. Необов'язковий аргумент рівень
вказує на якому рівні стеку почати відстеження.
Бібліотека math (математична бібліотека)
math.abs
math.abs( x )
Повертає модуль (абсолютне значення) x
.
math.acos
math.acos( x )
Повертає арккосинус x
(в радіанах).
math.asin
math.asin( x )
Повертає арксинус x
(в радіанах).
math.atan
math.atan( x )
Повертає арктангенс x
(в радіанах).
math.atan2
math.atan2( y, x )
Повертає арктангенс y/x
(в радіанах), використовуючи знаки обох аргументів для визначення того, в якій чверті знаходиться відповідь.
math.ceil
math.ceil( x )
Повертає найменше ціле число, яке більше чи рівне x
(округлення в більшу сторону).
math.cos
math.cos( x )
Повертає косинус x
(x задається в радіанах).
math.cosh
math.cosh( x )
Повертає гіперболічний косинус x
.
math.deg
math.deg( x )
Повертає кут x
(задано в радіанах) у градусах.
math.exp
math.exp( x )
Повертає .
math.floor
math.floor( x )
Повертає найменше ціле число, яке менше чи рівне x
(округлення в меншу сторону).
math.fmod
math.fmod( x, y )
Повертає остачу від ділення x
на y
, з часткою округленою в сторону нуля. Наприклад, math.fmod( 10, 3 )
повертає 1
.
math.frexp
math.frexp( x )
Повертає два значення m
та e
такі, що:
- Якщо
x
є кінцевим числом і не є нулем: , деe
ціле число, а абсолютне значенняm
лежить на проміжку . - Якщо
x
дорівнює нулю:m
таe
обидва дорівнюють 0. - Якщо
x
дорівнює NaN або нескінченності:m
дорівнюєx
, аe
дорівнює nil.
math.huge
Значення яке представляє додатню нескінченність. Це значення є рівним чи більшим за будь-яке інше числове значення.
math.ldexp
math.ldexp( m, e )
Повертає (e
має бути цілим числом).
math.log
math.log( x )
Повертає натуральний логарифм x
.
math.log10
math.log10( x )
Повертає десятковий логарифм x
.
math.max
math.max( x, ... )
Повертає найбільший аргумент із переданих.
Поведінка щодо NaN не визначена. В поточній реалізації функція поверне NaN якщо x
дорівнює NaN, але всі інші NaN будуть проігноровані.
math.min
math.min( x, ... )
Повертає найменший аргумент із переданих.
Поведінка щодо NaN не визначена. В поточній реалізації функція поверне NaN якщо x
дорівнює NaN, але всі інші NaN будуть проігноровані.
math.modf
math.modf( x )
Повертає два числа, які є відповідно цілою та дробною частинами x
. Наприклад, math.modf( 1.25 )
повертає 1, 0.25
.
math.pi
Повертає значення числа .
math.pow
math.pow( x, y )
Еквівалентне до x^y
.
math.rad
math.rad( x )
Переводить величину кута x
із градусів в радіани.
math.random
math.random( m, n )
Повертає псевдовипадкове число в межах від m
до n
.
Аргументи m
та n
можна пропустити, але якщо вони задані, то мають бути числами або значеннями які можна перевести в числа.
- Якщо жоден аргумент не заданий, повертає випадкове число в межах .
- Якщо задано лише один аргумент, повертає випадкове ціле число в межах .
- Якщо задані обидва аргументи, повертає випадкове ціле число в межах .
Note that incorrect output may be produced if m
or n
are less than −2147483648 or greater than 2147483647, or if n - m
is greater than 2147483646.
math.randomseed
math.randomseed( x )
Встановлює x
як зерно для генератора псевдовипадкових чисел.
Зверніть увагу, що використання однакового зерна змусить math.random
видавати однакові послідовності чисел.
math.randomseed( tonumber( mw.getContentLanguage():formatDate( "U" ) ) * 10000 + os.clock() * 10000 )
math.sin
math.sin( x )
Повертає синус x
(задається в радіанах).
math.sinh
math.sinh( x )
Повертає гіперболічний синус x
.
math.sqrt
math.sqrt( x )
Повертає квадратний корінь x
. Еквівалентне до x^0.5
.
math.tan
math.tan( x )
Повертає тангенс x
(задається в радіанах).
math.tanh
math.tanh( x )
Повертає гіперболічний тангенс x
.
Бібліотека os (бібліотека операційної системи)
os.clock
os.clock()
Повертає приблизний час виконання програми процесором в секундах.
os.date
os.date( format, time )
- formatDate з бібліотеки мов може бути використаний для складнішого форматування дати
Повертає текстовий рядок або таблицю, що містить дату і час, відформатовані відповідно до значення вказаного в змінній формат
. Якщо ця змінна пропущена або дорівнює nil, то за замовчуванням використовується «%c».
Якщо задана змінна time
, то саме час вказаний в цій змінній форматується (дивіться os.time()
). В іншому випадку форматується поточний час.
Якщо змінна формат
починається із символу «!», то дата форматується в форматі UTC а не в місцевому форматі. Якщо після цього символу або на самому початку рядка йде «*t», то дата повертається у вигляді таблиці з такими полями:
- year (рік)
- month (номер місяця в межах 1–12)
- day (день місяця в межах 1–31)
- hour (години в межах 0–23)
- min (хвилини в межах 0–59)
- sec (секунди в межах 0–59) (виняток: високосна секунда = 60)
- wday (номер дня тижня, де Неділя має номер 1)
- yday (день року)
- isdst (логічне значення яке вказує на те чи використовується літній та зимовий час)
Якщо змінна формат
не дорівнює «!», «*t» або «!*t», то дата форматується так само, як би це зробила функція [$url strftime] в мові програмування C.
os.difftime
os.difftime( t2, t1 )
Повертає різницю між моментами часу t1
та t2
в секундах.
os.time
os.time( table )
Повертає поточний час у вигляді часу Unix.
Якщо функція викликана без аргументів, повертається число для поточного часу. Якщо функції передано таблицю, то повертається число для часу вказаного в таблиці. Таблиця має містити поля «year», «month» та «day», а також може містити поля «hour» (за замовчуванням 12), «min» (за замовчуванням 0), «sec» (за замовчуванням 0) та «isdst».
Бібліотека package (бібліотека пакетів)
require
require( modulename )
Завантажує вказаний модуль.
Спочатку функція шукає значення для назви модуля в таблиці щоб перевірити чи був вже завантажений цей модуль (package.loaded[modulename]
). Якщо був, то повертається значення package.loaded[modulename]
.
В іншому випадку функція перевіряє кожен завантажувач з послідовності package.loaders
щоб знайти підходящий завантажувач для модуля. Якщо потрібний завантажувач знайдено, то він викликається і повертає значення package.loaded[modulename]
.
Дивіться документацію по package.loaders
для інформації про доступні завантажувачі.
Наприклад, якщо у вас є «Module:Giving» який містить наступне:
local p = {}
p.someDataValue = 'Привіт!'
return p
То це можна завантажити в іншому модулі за допомогою коду подібного до цього:
local giving = require( "Module:Giving" )
local value = giving.someDataValue -- value тепер має значення 'Привіт!'
package.loaded
Ця таблиця містить всі завантажені модулі. Ключами в ній є назви модулів, а значеннями є значення повернуті функцією require
при завантаженні цього модуля.
package.loaders
Ця таблиця містить послідовність пошукових функцій які використовуються при завантаженні модулів. Кожна пошукова функція викликається із єдиним аргументом яким є назва необхідного модуля. Якщо модуль знайдено, то пошукова функція має повернути іншу функцію, яка і завантажить модуль, та значення, яке має бути повернуте функцією require
. В іншому випадку функція має повернути nil.
В Scribunto є дві пошукові функції:
- Та яка шукає функцію-завантажувач в
package.preload[modulename]
. - Та яка шукає назву модуля в модулях Scribunto, а якщо не знаходить її там, то шукає в просторі назв «Module:» (або «Модуль:» в україномовних проєктах). Префікс «Module:» (або «Модуль:») має бути вказаним.
Зверніть увагу, що стандартні завантажувачі Lua не включені до цієї таблиці.
package.preload
Ця таблиця містить функції-завантажувачі, які використовуються першою пошуковою функцією Scribunto з package.loaders.
package.seeall
package.seeall( table )
Бібліотека string (бібліотека текстових рядків)
Всі функції пов'язані із текстовими рядками починають відлік символів в рядку з 1, на відміну від більшості інших мов програмування, де відлік починається з 0. Індекси також можуть бути від'ємними. В такому випадку вони рахуються з кінця текстового рядку. Індекс -1 означає останній символ в текстовому рядку, -2 передостанній і так далі.
Увага: Бібліотека string вважає всі символи в текстових рядках однобайтовими. Вона не може працювати із символами в кодуванні Unicode. Щоб працювати із символами в кодуванні Unicode, використовуйте відповідні методи з бібліотеки ustring.
string.byte
string.byte( s, i, j )
Ця функція вважає текстовий рядок масивом (послідовністю) байтів та повертає байтові значення для s[i]
, s[i+1]
, ···, s[j]
.
Значенням за замовчуванням для i
є 1.
Значенням за замовчуванням для j
є значення i
.
Ця функція є подібною до функції mw.ustring.byte().
string.char
string.char( ... )
Отримує одне чи більше цілих чисел. Повертає текстовий рядок, в якому всі отримані цілі числа перетворюються на відповідні символи.
local value = string.char( 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21 ) --value тепер має значення 'Привіт!'
Функція mw.ustring.char() є подібною до цієї, окрім того що вона трактує отримані цілі числа як коди Unicode, а не як байтові значення.
string.find
string.find( s, pattern, init, plain )
Шукає перший збіг аргументу pattern
в текстовому рядку s
. Якщо збіг знайдено, то повертається початкова і кінцева позиції цього збігу. В інакшому випадку повертається nil. Якщо в аргументі патерн
є групи, для яких є збіги, тоді ці збіги повертаються після початкової і кінцевої позицій.
Третій необов'язковий аргумент початковий індекс
вказує позицію, з якої починати пошук. За замовчуванням вважається рівним 1. Цей аргумент може мати негативне значення. Якщо четвертий необов'язковий аргумент простий пошук
вказаний рівним true, то аргумент патерн
розглядається як простий текстовий рядок, тобто функція просто шукає підрядок патерн
в текстовому рядку рядок
.
Зверніть увагу, що якщо аргумент простий пошук
заданий, то і аргумент початковий індекс
теж має бути заданим.
Функція mw.ustring.find() є подібною до цієї, окрім того що вона вважає текстовий рядок записаним в Unicode, а аргумент початковий індекс
вказує на позицію в символах, а не в байтах. Вона використовує патерни ustring, які працюють на основі властивостей символів Unicode.
string.format
string.format( formatstring, ... )
Ця функція повертає відформатовані версії всіх аргументів починаючи з другого відповідно до формату вказаного в аргументі форматування
, який має бути текстовим рядком.
Аргумент форматування
використовує обмежену підмножину специфікаторів формату printf
:
- Прапори «-», «+», " ", «#» та «0» розпізнаються.
- Поля для цілих чисел шириною до 99 розпізнаються. Прапор «*» не розпізнається.
- Точність цілих чисел до 99 знаку розпізнається. Прапор «*» не розпізнається.
- Модифікатори довжини не розпізнаються.
- Специфікаторами перетворення, які розпізнаються, є «c», «d», «i», «o», «u», «x», «X», «e», «E», «f», «g», «G», «s», «%» та нестандартний «q».
- Позиційні специфікатори (наприклад «%2$s») не розпізнаються.
Специфікатор перетворення «q» діє так само як і «s», окрім того що форматує текстовий рядок у форму, яка може бути безпечно прочитана інтерпретатором Lua. На початку і на кінці текстового рядка ставляться подвійні лапки, а всі подвійні лапки, переведення рядків, нульові символи та повернення на крок всередині цього текстового рядку замінюються на керуючі послідовності.
Перетворення текстових рядків та чисел одні в одного відбуваються так, як це описано в розділі Типи даних. Інші типи даних не перетворюються на текстові рядки автоматично. Текстові рядки, які містять нульові символи (символи з байтовим значенням 0) не оброблюються коректно.
Функція mw.ustring.format() є подібною до цієї.
string.gmatch
string.gmatch( s, pattern )
Повертає функцію-ітератор, яка під час кожного її виклику повертає збіг для наступної групи з патерн
в текстовому рядку рядок
. Якщо в аргументі патерн
не задані групи, то при кожному виклику функції повертається збіг для всього текстового рядка.
Ця функція не вважає символ «^» на початку патерн
магічним, оскільки це би унеможливило ітерації. Цей символ трактується буквально.
Функція mw.ustring.gmatch() є подібною до цієї. Вона використовує патерни ustring, які працюють на основі властивостей символів Unicode.
string.gsub
string.gsub( s, pattern, repl, n )
Повертає копію текстового рядка рядок
, в якому всі (або кількість вказана в кількість замін
на початку) збіги для патерн
заміняються на значення аргументу чим замінити
, який може бути текстовим рядком, таблицею або функцією. Також ця функція повертає кількість знайдених збігів як друге значення.
Якщо аргумент чим замінити
є текстовим рядком, то збіги заміняються саме на нього. В ньому символ «%» трактується як символ керуючої послідовності: кожна послідовність символів в текстовому рядку чим замінити
виду %d
, де d є цілим числом між 1 та 9, означає d-ну групу. Послідовність %0
означає весь збіг, а послідовність %%
означає один символ «%».
Якщо аргумент чим замінити
є таблицею, то кожний збіг заміняється на значення таблиці за ключем, який є першою групою. Якщо в патерн
не задані групи, то весь збіг використовується як ключ.
Якщо аргумент чим замінити
є функцією, то ця функція викликається для кожного збігу і групи передаються функції як аргументи. Якщо в патерн
не задані групи, то весь збіг передається функції як єдиний аргумент.
Якщо значення в таблиці чим замінити
або значення повернуте функцією чим замінити
є текстовим рядком або числом, то на нього і відбувається заміна. Якщо це значення дорівнює nil або false, то заміна не відбувається.
Функція mw.ustring.gsub() є подібною до цієї. Вона використовує патерни ustring, які працюють на основі властивостей символів Unicode.
string.len
string.len( s )
Повертає довжину текстового рядка рядок
в байтах. Якщо всередині текстового рядка присутній нульовий символ, то функція може видати неправильний результат. Функція еквівалентна до коду #рядок
.
Функція mw.ustring.len() є подібною до цієї, окрім того що вона вважає текстовий рядок записаним в Unicode.
string.lower
string.lower( s )
Повертає копію текстового рядку рядок
де всі великі літери замінені на маленькі. Всі інші символи не змінюються.
Функція mw.ustring.lower() є подібною до цієї, окрім того що вона вважає текстовий рядок записаним в Unicode.
string.match
string.match( s, pattern, init )
Шукає перший збіг для патерн
в текстовому рядку. Якщо функція знаходить збіг, то повертає групи з патерн
, в інакшому випадку повертає nil. Якщо в аргументі патерн
не задані групи, то повертається весь збіг.
Третій необов'язковий аргумент початковий індекс
вказує позицію, з якої починати пошук. За замовчуванням вважається рівним 1. Цей аргумент може мати негативне значення.
Функція mw.ustring.match() є подібною до цієї. Вона використовує патерни ustring, які працюють на основі властивостей символів Unicode.
string.rep
string.rep( s, n )
Повертає текстовий рядок, де s
повторюється n
разів підряд. Функція mw.ustring.rep() є подібною до цієї.
string.reverse
string.reverse( s )
Повертає текстовий рядок, в якому всі символи рядка s
записані в зворотному порядку (побайтово).
string.sub
string.sub( s, i, j )
Повертає підрядок текстового рядка s
, який починається з символа в позиції i
і закінчується символом в позиції j
. Аргументи i
та j
можуть бути негативними. Якщо j
дорівнює нулю або пропущено, воно триватиме до кінця рядка.
Виклик функції string.sub(s,1,j)
повертає префікс текстового рядка s
довжиною j
, а виклик string.sub(s,1,j)
і повертає суфікс довжиною i
.
Функція mw.ustring.sub() є подібною до цієї, окрім того що вона вважає текстовий рядок записаним в Unicode.
string.ulower
string.ulower( s )
An alias for mw.ustring.lower().
string.upper
string.upper( s )
Повертає копію текстового рядку рядок
де всі маленькі літери замінені на великі. Всі інші символи не змінюються.
Функція mw.ustring.upper() є подібною до цієї, окрім того що вона вважає текстовий рядок записаним в Unicode.
string.uupper
string.uupper( s )
An alias for mw.ustring.upper().
Патерни
Зверніть увагу, що патерни в Lua схожими на регулярні вирази, але вони не однакові. Існують такі відмінності від регулярних виразів та регулярних виразів Perl:
- Символом посилання на групу та буквального включення є символ відсотка (
%
), а не обернений слеш (\
).
- Точка (
.
) збігається зі всіма символами, в тому числі із змінами рядка.
- Не існує режиму нечутливості до регістру.
- Не існує оператора вибору (оператор
|
).
- Квантифікатори (
*
,+
,?
та-
) застосовуються тільки до окремих символів або класів символів, вони не застосовуються до груп.
- Єдиним нежадібним квантифікатором є
-
, який еквівалентний до квантифікатора*?
в Perl.
- Не існує узагальнених кінцевих квантифікаторів (
{n,m}
в Perl).
- Єдиними твердженнями нульової ширини є
^
,$
та%f[set]
. Твердження, такі як\b
або(?=···)
в Perl, не підтримуються.
- Patterns themselves do not recognize character escapes such as
\ddd
. However, since patterns are strings these sort of escapes may be used in the string literals used to create the pattern-string.
Також зверніть увагу що патерни не можуть містити нульові символи (символи з байтовим значенням 0). Використовуйте натомість %z
.
Дивіться також розділ Патерни ustring, для інформації про патерни для текстових рядків в кодуванні Unicode.
Класи символів
Клас символів використовується щоб представити певний набір символів. При описанні символу, дозволяються такі послідовності:
x
|
(де x не є одним з магічних символів ^$()%.[]*+-? ) представляє сам символ x.
|
---|---|
.
|
(точка) представляє всі символи. |
%a
|
представляє всі літери ASCII. |
%c
|
представляє всі контрольні символи ASCII. |
%d
|
представляє всі цифри. |
%l
|
* %l : представляє всі маленькі літери ASCII.
|
%p
|
представляє всі знаки пунктуації. |
%s
|
представляє всі пробільні символі. |
%u
|
представляє всі великі літери ASCII. |
%w
|
представляє всі літери та цифри ASCII. |
%x
|
представляє всі шістнадцяткові цифри. |
%z
|
представляє нульовий символ (символ із байтовим значенням 0). |
%A
|
представляє всі символи, які не містяться в %a .
|
%C
|
представляє всі символи, які не містяться в %c .
|
%D
|
представляє всі символи, які не містяться в %d .
|
%L
|
представляє всі символи, які не містяться в %l .
|
%P
|
представляє всі символи, які не містяться в %p .
|
%S
|
представляє всі символи, які не містяться в %s .
|
%U
|
представляє всі символи, які не містяться в %u .
|
%W
|
представляє всі символи, які не містяться в %w .
|
%X
|
представляє всі символи, які не містяться в %x .
|
%Z
|
представляє всі символи, які не містяться в %z .
|
%y
|
(де $x є будь-яким символом, який не є літерою або цифрою) представляє сам символ $x. Це стандартний спосіб уникнути трактування символу як магічного. Перед кожним знаком пунктуації (навіть тим, який не є магічним символом) можна поставити символ '% ' щоб символ x представляв сам себе, а не був магічним символом.
|
[set]
|
представляє клас, який містить всі символи та класи символів перелічені в set. Можна також задати діапазон символів вказавши початковий і кінцевий символи діапазону розділені знаком ' Взаємодія діапазонів та класів символів не задана, тому патерни виду |
[^set]
|
представляє всі символи, які не входять до set. Сам set трактується так само, як і в попередньому пункті. |
Патерн-вирази
Патерн-виразами можуть бути
- один вказівник класу виразів, який відповідає одному символу з цього класу;
- один вказівник класу виразів перед символом '
*
', які відповідають 0 або більше повторенням символу з класу. Ці вирази для вказання повторюваних символів завжди відповідають найдовшій можливій послідовності символів; - один вказівник класу виразів перед символом '
+
', які відповідають 1 або більше повторенням символу з класу. Ці вирази для вказання повторюваних символів завжди відповідають найдовшій можливій послідовності символів;
- один вказівник класу виразів перед символом '
-
', які відповідають 0 або більше повторенням символу з класу. На відміну від «*
», ці вирази для вказання повторюваних символів завжди відповідають найкоротшій можливій послідовності символів;
- один вказівник класу виразів перед символом '
?
', які відповідають 0 або 1 повторенням символу з класу; %n
, де n є цифрою від 1 до 9; такий вираз відповідає частині рядка рівній n-ому знайденому рядку (див. нижче);%bxy
, де x та y є двома різними символами; такий вираз відповідає рядку який починається з x, закінчується на y, і де x та y є збалансованими. Це означає що якщо хтось читає рядок зліва направо, додаючи 1 знайшовши x і віднімаючи 1 знайшовши y, то знайдений рядок закінчиться на y в якому рахунок вперше прийме значення 0. Наприклад, вираз%b()
відповідає рядкам зі збалансованими дужками.%f[set]
є патерном країв; такий вираз відповідає порожньому рядку в будь-якій позиції так, що наступний символ належить до набору set, а попередній не належить. Набір set інтерпретується як це було описано вище. Початок та кінець рядка оброблюються так, ніби вони є символом '\0'.
Зверніть увагу, що патерни країв були присутніми, але незадокументованими, в Lua 5.1, і були додані офіційно лише до Lua 5.2. Принцип їх роботи в Lua 5.2.1 такий самий як був у 5.1.0.
Патерн
Патерн є послідовністю патерн-виразів.
Символ «^
» на початку патерну позначає шукомий підрядок який знаходиться на початку рядка, в якому відбувається пошук. Символ «$
» в кінці патерну позначає підрядок у кінці. В інших місцях «^
» та «$
» не мають спеціального значення та позначають самі себе.
A $
at the end of a pattern anchors the match at the end of the subject string. At other positions, ^
and $
have no special meaning and represent themselves.
Групи
Патерн може містити підпатерни у дужках; вони описують групи. Коли за патерном отримується підрядок, його частини, які відповідають групам, зберігаються ("згруповуються") для використання в майбутньому. Групи нумеруються за їхніми лівими відкриваючими дужками, і посилаються на %
-prefix: %1
, %2
(в PCRE:
) Наприклад, в патерні (a*(.)%w(%s*))
(a*(.)%w(%s*))
, частина a*(.)%w(%s*)
зберігається в першій групі (і тому має номер 1); символ що відповідає .
зберігається в групі із номером 2, а частина що відповідає послідовності %s*
має номер 3.
Посилання на групи можуть з'являтися в патерні і вони посилаються на текст, який був раніше віднесений до групи в цьому патерні. Наприклад, ([a-z])%1
відповідає будь-якій парі однакових маленьких літер, а ([a-z])([a-z])([a-z])[a-z]%3%2%1
відповідає будь-якому паліндрому із семи літер.
В якості особливого випадку, порожня група ()
відповідає поточній позиції в рядку (число). Наприклад, якщо ми використаємо патерн "()aa()"
для рядка "flaaap"
, то ми отримаємо дві групи зі значеннями 3 та 5.
Known limitations: Unlike Ustring library patterns, String library patterns may not contain more than 32 captures. If the pattern has more, then the String function will throw an error. Because the Ustring library has its own maximum of 10,000 bytes for patterns (unlike the String library), it is therefore impossible to use a pattern which exceeds both limits, as it will be incompatible with both libraries.
Бібліотека table (бібліотека таблиць)
Більшість функцій в бібліотеці table вважають що таблиці є послідовностями.
Функції table.foreach()
, table.foreachi()
та table.getn()
доступні, але їх використання є небажаним. Замість них використовуйте цикл for із функцією pairs(), цикл for із функцією ipairs() або оператор довжини.
table.concat
table.concat( table, sep, i, j )
Отримавши масив в якому всі елементи є текстовими рядками або числами, повертає всі значення від i-го до j-го розділені символом sep
у виглядіtable[i] .. sep .. table[i+1] .. sep .. table[j]
.
Значенням за замовчуванням для sep
є порожній рядок, для i
значенням за замовчуванням є 1, а для j
— довжина таблиці.
table.insert
table.insert( table, value )
table.insert( table, pos, value )
Вставляє елемент value
на позицію pos
в таблиці table
, зміщуючи всі наступні елементи, якщо потрібно. Для pos
значенням за замовчуванням є довжина таблиці плюс 1. Таким чином table.insert(t, x)
вставляє x
в самий кінець таблиці t
.
Елементи після #table
зміщуються; див. Оператор довжини для застережень щодо таблиць які не є послідовностями.
Note: when using the pos
parameter, value
should not be nil
. Attempting to insert an explicit nil
value into the middle of a table will result in undefined behaviour, which may delete elements in the table unpredictably.
table.maxn
table.maxn( table )
Повертає найбільший додатній числовий індекс таблиці, або нуль якщо в таблиці таких нема.
Щоб зробити це, функція переглядає всі елементи таблиці. Функція приблизно еквівалентна такому коду:
function table.maxn( table )
local maxn, k = 0, nil
repeat
k = next( table, k )
if type( k ) == 'number' and k > maxn then
maxn = k
end
until not k
return maxn
end
table.remove
table.remove( table, pos )
Видаляє із таблиці table
елемент в позиції pos
, і, якщо потрібно, зміщує наступний елемент на його місце, а наступний після нього на місце попереднього, і так до кінця таблиці. Повертає значення видаленого елемента. Значенням за замовчуванням для pos
є довжина таблиці, тому table.remove( t )
видалить останній елемент таблиці t
.
Елементи після #table
зміщуються; див. Оператор довжини для застережень щодо таблиць які не є послідовностями.
table.sort
table.sort( table, comp )
Сортує елементи таблиці в заданному порядку, перебираючи їх по порядку від table[1]
до table[#table]
. Якщо задано comp
, то це має бути функція якій передаються два елементи таблиці і яка повертає логічне значення true якщо перший має передувати другому (так щоб not comp(a[i+1],a[i])
повертав true після сортування). Якщо comp
не задано, використовується стандартний оператор порівняння <
.
If comp
is given, then it must be a function that receives two table elements, and returns true
when the first is less than the second (so that not comp(a[i+1],a[i])
will be true after the sort).
If comp
is not given, then the standard Lua operator <
is used instead.
Алгоритм сортування не є стабільним; це значить що для елементів які вважатимуться рівними в цьому порядку, відносні позиції можуть помінятися.
Бібліотеки Scribunto
Всі бібліотеки Scribunto розташовані в таблиці mw
.
Основні функції
mw.addWarning
mw.addWarning( text )
Додає попередження яке показується перед попереднім переглядом редагування. text
оброблюється як вікірозмітка.
mw.allToString
mw.allToString( ... )
Перетворює всі аргументи на текстові рядки за допомогою методу tostring(), після чого об'єднує їх в один текстовий рядок, де вони розділені символами табуляції в якості розділювача.
mw.clone
mw.clone( value )
Створює глибоку копію аргументу. Всі таблиці (і їхні метатаблиці) створюються з нуля. Функції, однак, все одно є спільними.
mw.getCurrentFrame
mw.getCurrentFrame()
Повертає поточний об'єкт frame, зазвичай об'єкт frame із останнього #invoke
.
mw.incrementExpensiveFunctionCount
mw.incrementExpensiveFunctionCount()
Збільшує кількість «ресурсомістких викликів функцій» на одиницю і генерує виняток якщо нове значення перевищує ліміт (див. $wgExpensiveParserFunctionLimit
).
mw.isSubsting
mw.isSubsting()
Повертає логічне значення true якщо поточний #invoke
вставляється підстановкою, в іншому випадку повертає false. Див. розділ Повернення тексту вище для пояснення відмінностей між підстановкою і непідстановкою.
mw.loadData
mw.loadData( module )
Інколи модуль потребує великих таблиць даних; наприклад, загальновживаний модуль переведення одиниць вимірювання може потребувати великої таблиці одиниць вимірювання та їх коефіцієнтів конвертації. Інколи такі модулі можуть використовуватись багато разів на одній сторінці. Обробка великої таблиці даних для кожного {{#invoke:}}
може зайняти багато часу. Щоб уникнути цієї проблеми існує mw.loadData()
.
mw.loadData
працює так само як require()
, із такими відмінностями:
- Завантажений модуль обчислюється тільки один раз для кожної сторінки, а не по одному разу для кожного виклику
{{#invoke:}}
.
- The loaded module is not recorded in
package.loaded
.
- The value returned from the loaded module must be a table. Other data types are not supported.
- The returned table (and all subtables) may contain only booleans, numbers, strings, and other tables. Other data types, particularly functions, are not allowed.
- The returned table (and all subtables) may not have a metatable.
- All table keys must be booleans, numbers, or strings.
- The table actually returned by
mw.loadData()
has metamethods that provide read-only access to the table returned by the module. Since it does not contain the data directly,pairs()
andipairs()
will work but other methods, including#value
,next()
, and the functions in the Table library, will not work correctly.
Гіпотетичний модуль переведення одиниць вимірювання, згаданий вище, може містити свій виконуваний код в «Module:Convert», а дані для його роботи в «Module:Convert/data». Тоді «Module:Convert» використовуватиме local data = mw.loadData( 'Module:Convert/data' )
для ефективного завантаження даних.
mw.loadJsonData
mw.loadJsonData( page )
This is the same as mw.loadData()
above, except it loads data from JSON pages rather than Lua tables.
The JSON content must be an array or object.
See also mw.text.jsonDecode()
.
mw.dumpObject
mw.dumpObject( object )
Серіалізує object
у вигляд придатний для читання людиною, після чого повертає результуючий текстовий рядок.
mw.log
mw.log( ... )
Передає аргументи до функції mw.allToString(), після чого додає результуючий текстовий рядок до буфера журналу.
В консолі налагодження функція print()
є ідентичною до цієї.
mw.logObject
mw.logObject( object )
mw.logObject( object, prefix )
Викликає функцію mw.dumpObject() та додає результуючий текстовий рядок до буфера журналу. Якщо надано аргумент prefix
, він, разом із знаком рівності, буде доданий до буферу журналу перед серіалізованим текстовим рядком (тобто, до журналу буде доданий текст «prefix = object-string»).
Об'єкт frame
Об'єкт frame є інтерфейсом для параметрів переданих до {{#invoke:}}
та до його парсера.
Note that there is no frame library, and there is no global variable named frame
. A frame object is typically obtained by being passed as a parameter to the function called by {{#invoke:}}
, and can also be obtained from mw.getCurrentFrame()
.
frame.args
Таблиця для отримання доступу до аргументів переданих до фрейму. Наприклад, якщо модуль викликається із вікітексту за допомогою коду
{{#invoke:module|function|arg1|arg2|name=arg3}}
то frame.args[1]
поверне "arg1"
, frame.args[2]
поверне "arg2"
, а frame.args['name']
(або frame.args.name
) поверне "arg3"
. Також, є можливим обробити всі аргументи використовуючи функцію pairs( frame.args )
або ipairs( frame.args )
.
However, due to how Lua implements table iterators, iterating over arguments will return them in an unspecified order, and there's no way to know the original order as they appear in wikitext.
Зверніть увагу, що значення в цій таблиці завжди є текстовими рядками; tonumber()
може за потреби використовуватись для перетворення їх у числа. Ключі, однак, є числами навіть якщо вони прямо вказані у виклику модуля: {{#invoke:module|function|1|2=2}}
передає текстові значення "1"
та "2"
що індексуються числовими значеннями 1
та 2
.
Як і при включенні шаблонів на сайтах із рушієм MediaWiki, в іменованих аргументах, перед їх передачею до модуля, будуть прибрані пробіли на початку і в кінці, як в назві аргумента, так і в його значенні. При цьому, в неіменованих аргументах пробіли не прибираються.
З міркувань оптимізації, frame.args
використовує метатаблицю замість прямого включення аргументів. Значення аргументів запитуються рушієм MediaWiki тільки коли вони потрібні. Це означає що більшість інших методів таблиць працюватимуть некоректно, включаючи #frame.args
, next( frame.args )
та функції з бібліотеки table.
Якщо в аргументі включеному до #invoke був використаний препроцесорний синтаксис, такий як включення шаблонів або аргументи в потрійних фігурних дужках, він буде оброблений до передачі в модуль. Якщо деякі спеціальні теги написані в нотації XML, наприклад <pre>
, <nowiki>
, <gallery>
або <ref>
, містяться в аргументах що передаються #invoke, вони будуть перетворені на «стріп-маркери» — спеціальні текстові рядки які починаються із символа видалення (ASCII 127), які після повернення з #invoke заміняються розміткою HTML.
frame:callParserFunction
frame:callParserFunction( name, args )
frame:callParserFunction( name, ... )
frame:callParserFunction{ name = string, args = table }
- Зверніть увагу на використання іменованих аргументів.
Call a parser function, returning an appropriate string. This is preferable to frame:preprocess
, but whenever possible, native Lua functions or Scribunto library functions should be preferred to this interface.
The following calls are approximately equivalent to the indicated wikitext:
-- {{ns:0}}
frame:callParserFunction( 'ns', { 0 } )
frame:callParserFunction( 'ns', 0 )
frame:callParserFunction{ name = 'ns', args = { 0 } }
-- {{#tag:nowiki|some text}}
frame:callParserFunction( '#tag', { 'nowiki', 'some text' } )
frame:callParserFunction( '#tag', 'nowiki', 'some text' )
frame:callParserFunction( '#tag:nowiki', 'some text' )
frame:callParserFunction{ name = '#tag', args = { 'nowiki', 'some text' } }
-- {{#tag:ref|some text|name=foo|group=bar}}
frame:callParserFunction( '#tag', { 'ref',
'some text', name = 'foo', group = 'bar'
} )
Note that, as with frame:expandTemplate(), the function name and arguments are not preprocessed before being passed to the parser function.
frame:expandTemplate
frame:expandTemplate{ title = title, args = table }
- Note the use of named arguments.
This is equivalent to a call to frame:callParserFunction() with function name 'msg'
(see Help:Magic words#Transclusion modifiers) and with title
prepended to args
.
This is transclusion. The call:
frame:expandTemplate{ title = 'template', args = { 'arg1', 'arg2', name = 'arg3' } }
does roughly the same thing from Lua that {{template|arg1|arg2|name=arg3}}
does in wikitext. As in transclusion, if the passed title does not contain a namespace prefix it will be assumed to be in the Template: namespace.
Note that the title and arguments are not preprocessed before being passed into the template:
-- This is roughly equivalent to wikitext like {{template|{{!}}}}
frame:expandTemplate{ title = 'template', args = { '|' } }
frame:callParserFunction{ 'msg', { 'template', '|' } }
-- This is roughly equivalent to wikitext like {{template|{{((}}!{{))}}}}
frame:expandTemplate{ title = 'template', args = { '{{!}}' } }
frame:callParserFunction{ 'msg', { 'template', '{{!}}' } }
frame:extensionTag
frame:extensionTag( name, content, args )
frame:extensionTag{ name = string, content = string, args = table_or_string }
This is equivalent to a call to frame:callParserFunction() with function name '#tag'
(see Help:Magic_words#Miscellaneous) and with name
and content
prepended to args
.
-- These are equivalent
frame:extensionTag( 'ref', 'some text', { name = 'foo', group = 'bar' } )
frame:extensionTag{ name = 'ref', content = 'some text', args = { name = 'foo', group = 'bar' } }
frame:callParserFunction( '#tag', { 'ref' ,
'some text', name = 'foo', group = 'bar'
} )
-- These are equivalent
frame:extensionTag{ name = 'ref', content = 'some text', args = { 'some other text' } }
frame:callParserFunction( '#tag', { 'ref',
'some text', 'some other text'
} )
frame:getParent
frame:getParent()
Called on the frame created by {{#invoke:}}
, returns the frame for the page that called {{#invoke:}}
. Called on that frame, returns nil.
For instance, if the template {{Example}}
contains the code {{#invoke:ModuleName|FunctionName|A|B}}
, and a page transcludes that template with the code {{Example|C|D}}
, then in Module:ModuleName, calling frame.args[1]
and frame.args[2]
returns "A"
and "B"
, and calling frame:getParent().args[1]
and frame:getParent().args[2]
returns "C"
and "D"
, with frame
being the first argument in the function call.
frame:getTitle
frame:getTitle()
Returns the title associated with the frame as a string. For the frame created by {{#invoke:}}
, this is the title of the module invoked.
frame:newChild
frame:newChild{ title = title, args = table }
- Note the use of named arguments.
Create a new Frame object that is a child of the current frame, with optional arguments and title.
This is mainly intended for use in modules that call other modules whose name is defined by the caller (e.g. {{#invoke:params|concat_and_invoke}}
), or in the debug console for testing functions that would normally be called by {{#invoke:}}
. The number of frames that may be created at any one time is limited.
frame:preprocess
frame:preprocess( string )
frame:preprocess{ text = string }
This expands wikitext in the context of the frame, i.e. templates, parser functions, and parameters such as {{{1}}}
are expanded, and returns the expanded text. Certain special tags written in XML-style notation, such as <pre>
, <nowiki>
, <gallery>
and <ref>
, will be replaced with "strip markers" — special strings which begin with a delete character (ASCII 127), to be replaced with HTML after they are returned from #invoke
.
If you are expanding a single template, use frame:expandTemplate
instead of trying to construct a wikitext string to pass to this method. It's faster and less prone to error if the arguments contain pipe characters or other wikimarkup.
If you are expanding a single parser function, use frame:callParserFunction
for the same reasons.
frame:getArgument
frame:getArgument( arg )
frame:getArgument{ name = arg }
Gets an object for the specified argument, or nil if the argument is not provided.
The returned object has one method, object:expand()
, that returns the expanded wikitext for the argument.
frame:newParserValue
frame:newParserValue( text )
frame:newParserValue{ text = text }
Returns an object with one method, object:expand()
, that returns the result of frame:preprocess( text )
.
frame:newTemplateParserValue
frame:newTemplateParserValue{ title = title, args = table }
- Note the use of named arguments.
Returns an object with one method, object:expand()
, that returns the result of frame:expandTemplate
called with the given arguments.
frame:argumentPairs
frame:argumentPairs()
Same as pairs( frame.args )
. Included for backwards compatibility.
Бібліотека hash (бібліотека хеш-функцій)
mw.hash.hashValue
mw.hash.hashValue( algo, value )
Hashes a string value with the specified algorithm. Valid algorithms may be fetched using mw.hash.listAlgorithms().
mw.hash.listAlgorithms
mw.hash.listAlgorithms()
Returns a list of supported hashing algorithms, for use in mw.hash.hashValue().
Бібліотека HTML
mw.html
is a fluent interface for building complex HTML from Lua. On many Wikimedia wikis this was formerly implemented in Module:HtmlBuilder
. A mw.html object can be created using mw.html.create
.
Functions documented as mw.html.name
are available on the global mw.html
table; functions documented as mw.html:name
and html:name
are methods of an mw.html object (see mw.html.create
).
A basic example could look like this:
local div = mw.html.create( 'div' )
div
:attr( 'id', 'testdiv' )
:css( 'width', '100%' )
:wikitext( 'Some text' )
:tag( 'hr' )
return tostring( div )
-- Output: <div id="testdiv" style="width:100%;">Some text<hr /></div>
mw.html.create
mw.html.create( tagName, args )
Creates a new mw.html object containing a tagName
html element. You can also pass an empty string or nil as tagName
in order to create an empty mw.html object.
args
can be a table with the following keys:
args.selfClosing
: Force the current tag to be self-closing, even if mw.html doesn't recognize it as self-closingargs.parent
: Parent of the current mw.html instance (intended for internal usage)
mw.html:node
html:node( builder )
Appends a child mw.html (builder
) node to the current mw.html instance. If a nil parameter is passed, this is a no-op. A (builder
) node is a string representation of an html element.
mw.html:wikitext
html:wikitext( ... )
Appends an undetermined number of wikitext strings to the mw.html object.
Note that this stops at the first nil item.
Basic wikitext will get parsed, like HTML, links, bold, lists or tables. However, templates and parser functions won't be evaluated if they are passed directly to this function, unless they came from template parameters. Those will be rendered in plain text instead. To evaluate them, they'll have to be passed through frame:preprocess.
mw.html:newline
html:newline()
Appends a newline to the mw.html object. Useful when used before and after mw.html:wikitext(), when the wikitext contains lists or tables, whose syntax only has a special meaning when present at the start of a line.
mw.html:tag
html:tag( tagName, args )
Appends a new child node with the given tagName
to the builder, and returns a mw.html instance representing that new node. The args
parameter is identical to that of mw.html.create
Note that contrarily to other methods such as html:node()
, this method doesn't return the current mw.html instance, but the mw.html instance of the newly inserted tag.
Make sure to use html:done()
to go up to the parent mw.html instance, or html:allDone()
if you have nested tags on several levels.
mw.html:attr
html:attr( name, value )
html:attr( table )
Set an HTML attribute with the given name
and value
on the node. Alternatively a table holding name->value pairs of attributes to set can be passed. In the first form, a value of nil causes any attribute with the given name to be unset if it was previously set.
mw.html:getAttr
html:getAttr( name )
Get the value of a html attribute previously set using html:attr()
with the given name
.
mw.html:addClass
html:addClass( class )
Adds a class name to the node's class attribute. If a nil parameter is passed, this is a no-op.
mw.html:css
html:css( name, value )
html:css( table )
Set a CSS property with the given name
and value
on the node. Alternatively a table holding name->value pairs of properties to set can be passed. In the first form, a value of nil causes any property with the given name to be unset if it was previously set.
mw.html:cssText
html:cssText( css )
Add some raw css
to the node's style attribute. If a nil parameter is passed, this is a no-op.
mw.html:done
html:done()
Returns the parent node under which the current node was created. Like jQuery.end, this is a convenience function to allow the construction of several child nodes to be chained together into a single statement.
mw.html:allDone
html:allDone()
Like html:done()
, but traverses all the way to the root node of the tree and returns it.
Бібліотека language (бібліотека мов)
Language codes are described at language code. Many of MediaWiki's language codes are similar to IETF language tags, but not all MediaWiki language codes are valid IETF tags or vice versa.
Functions documented as mw.language.name
are available on the global mw.language
table; functions documented as mw.language:name
and lang:name
are methods of a language object (see mw.language.new
or mw.language.getContentLanguage
).
mw.language.fetchLanguageName
mw.language.fetchLanguageName( code, inLanguage )
The full name of the language for the given language code: native name (language autonym) by default, name translated in target language if a value is given for inLanguage.
mw.language.fetchLanguageNames
mw.language.fetchLanguageNames()
mw.language.fetchLanguageNames( inLanguage )
mw.language.fetchLanguageNames( inLanguage, include )
Fetch the list of languages known to MediaWiki, returning a table mapping language code to language name.
By default the name returned is the language autonym; passing a language code for inLanguage returns all names in that language.
By default, only language names known to MediaWiki are returned; passing 'all'
for include will return all available languages (from Extension:CLDR ), while passing 'mwfile'
will include only languages having customized messages included with MediaWiki core or enabled extensions. To explicitly select the default, 'mw'
may be passed.
mw.language.getContentLanguage
mw.language.getContentLanguage()
mw.getContentLanguage()
Returns a new language object for the wiki's default content language.
mw.language.getFallbacksFor
mw.language.getFallbacksFor( code )
Returns a list of MediaWiki's fallback language codes for the specified code.
mw.language.isKnownLanguageTag
mw.language.isKnownLanguageTag( code )
Returns true
if a language code is known to MediaWiki.
A language code is "known" if it is a "valid built-in code" (i.e. it returns true
for mw.language.isValidBuiltInCode
) and returns a non-empty string for mw.language.fetchLanguageName
.
mw.language.isSupportedLanguage
mw.language.isSupportedLanguage( code )
Checks whether any localisation is available for that language code in MediaWiki.
A language code is "supported" if it is a "valid" code (returns true
for mw.language.isValidCode
), contains no uppercase letters, and has a message file in the currently-running version of MediaWiki.
It is possible for a language code to be "supported" but not "known" (i.e. returning true
for mw.language.isKnownLanguageTag
). Also note that certain codes are "supported" despite mw.language.isValidBuiltInCode
returning false
.
mw.language.isValidBuiltInCode
mw.language.isValidBuiltInCode( code )
Returns true
if a language code is of a valid form for the purposes of internal customisation of MediaWiki.
The code may not actually correspond to any known language.
A language code is a "valid built-in code" if it is a "valid" code (i.e. it returns true
for mw.language.isValidCode
); consists of only ASCII letters, numbers, and hyphens; and is at least two characters long.
Note that some codes are "supported" (i.e. returning true
from mw.language.isSupportedLanguage
) even though this function returns false
.
mw.language.isValidCode
mw.language.isValidCode( code )
Returns true
if a language code string is of a valid form, whether or not it exists. This includes codes which are used solely for customisation via the MediaWiki namespace.
The code may not actually correspond to any known language.
A language code is valid if it does not contain certain unsafe characters (colons, single- or double-quotes, slashs, backslashs, angle brackets, ampersands, or ASCII NULs) and is otherwise allowed in a page title.
mw.language.new
mw.language.new( code )
mw.getLanguage( code )
Creates a new language object. Language objects do not have any publicly accessible properties, but they do have several methods, which are documented below.
There is a limit of 200 on the number of distinct language codes that may be used on a page. Exceeding this limit will result in errors.
mw.language:getCode
lang:getCode()
Returns the language code for this language object.
mw.language:toBcp47Code
lang:toBcp47Code()
Returns the standard BCP-47 language code for this language object. This is the code string which is appropriate to use in HTML, for example as the value of a lang
attribute.
mw.language:getFallbackLanguages
lang:getFallbackLanguages()
Returns a list of MediaWiki's fallback language codes for this language object. Equivalent to mw.language.getFallbacksFor( lang:getCode() )
.
mw.language:isRTL
lang:isRTL()
Returns true
if the language is written right-to-left, false
if it is written left-to-right.
mw.language:lc
lang:lc( s )
Converts the string to lowercase, honoring any special rules for the given language.
When the Ustring library is loaded, the mw.ustring.lower() function is implemented as a call to mw.language.getContentLanguage():lc( s )
.
mw.language:lcfirst
lang:lcfirst( s )
Converts the first character of the string to lowercase, as with lang:lc()
.
mw.language:uc
lang:uc( s )
Converts the string to uppercase, honoring any special rules for the given language.
When the Ustring library is loaded, the mw.ustring.upper()
function is implemented as a call to mw.language.getContentLanguage():uc( s )
.
mw.language:ucfirst
lang:ucfirst( s )
Converts the first character of the string to uppercase, as with lang:uc().
mw.language:caseFold
lang:caseFold( s )
Converts the string to a representation appropriate for case-insensitive comparison. Note that the result may not make any sense when displayed.
mw.language:formatNum
lang:formatNum( n )
lang:formatNum( n, options )
Formats a number with grouping and decimal separators appropriate for the given language. Given 123456.78, this may produce "123,456.78", "123.456,78", or even something like "١٢٣٬٤٥٦٫٧٨" depending on the language and wiki configuration.
The options
is a table of options, which can be:
noCommafy
: Settrue
to omit grouping separators and use a dot (.
) as the decimal separator.
Digit transformation may still occur, which may include transforming the decimal separator.
mw.language:formatDate
lang:formatDate( format, timestamp, local )
Formats a date according to the given format string. If timestamp
is omitted, the default is the current time. The value for local
must be a boolean or nil; if true
, the time is formatted in the wiki's local time rather than in UTC.
The format string and supported values for timestamp
are identical to those for the #time parser function from Extension:ParserFunctions .
Note however that backslashes may need to be doubled in a Lua string literal, since Lua also uses backslash as an escape character while wikitext does not:
-- This string literal contains a newline, not the two characters "\n", so it is not equivalent to {{#time:\n}}.
lang:formatDate( '\n' )
-- This is equivalent to {{#time:\n}}, not {{#time:\\n}}.
lang:formatDate( '\\n' )
-- This is equivalent to {{#time:\\n}}, not {{#time:\\\\n}}.
lang:formatDate( '\\\\n' )
mw.language:formatDuration
lang:formatDuration( seconds )
lang:formatDuration( seconds, chosenIntervals )
Breaks a duration in seconds into more human-readable units, e.g. 12345 to 3 hours, 25 minutes and 45 seconds, returning the result as a string.
chosenIntervals
, if given, is a table with values naming the interval units to use in the response. These include 'millennia
', 'centuries
', 'decades
', 'years
', 'weeks
', 'days
', 'hours
', 'minutes
', and 'seconds
'.
mw.language:parseFormattedNumber
lang:parseFormattedNumber( s )
This takes a number as formatted by lang:formatNum() and returns the actual number. In other words, this is basically a language-aware version of tonumber()
.
mw.language:convertPlural
lang:convertPlural( n, ... )
lang:convertPlural( n, forms )
lang:plural( n, ... )
lang:plural( n, forms )
This chooses the appropriate grammatical form from forms
(which must be a sequence table) or ...
based on the number n
. For example, in English you might use n .. ' ' .. lang:plural( n, 'sock', 'socks' )
or n .. ' ' .. lang:plural( n, { 'sock', 'socks' } )
to generate grammatically-correct text whether there is only 1 sock or 200 socks.
The necessary values for the sequence are language-dependent, see localization of magic words and translatewiki's FAQ on PLURAL for some details.
mw.language:convertGrammar
lang:convertGrammar( word, case )
lang:grammar( case, word )
- Note the different parameter order between the two aliases.
convertGrammar
matches the order of the method of the same name on MediaWiki's Language object, whilegrammar
matches the order of the parser function of the same name, documented at Help:Magic words#Localisation.
This chooses the appropriate inflected form of word
for the given inflection code case
.
The possible values for word
and case
are language-dependent, see Special:MyLanguage/Help:Magic words#Localisation and translatewiki:Grammar for some details.
mw.language:gender
lang:gender( what, masculine, feminine, neutral )
lang:gender( what, { masculine, feminine, neutral } )
Chooses the string corresponding to the gender of what
, which may be "male", "female", or a registered user name.
mw.language:getArrow
lang:getArrow( direction )
Returns a Unicode arrow character corresponding to direction
:
- forwards: Either "→" or "←" depending on the directionality of the language.
- backwards: Either "←" or "→" depending on the directionality of the language.
- left: "←"
- right: "→"
- up: "↑"
- down: "↓"
mw.language:getDir
lang:getDir()
Returns "ltr" or "rtl", depending on the directionality of the language.
mw.language:getDirMark
lang:getDirMark( opposite )
Returns a string containing either U+200E (the left-to-right mark) or U+200F (the right-to-left mark), depending on the directionality of the language and whether opposite
is a true or false value.
mw.language:getDirMarkEntity
lang:getDirMarkEntity( opposite )
Returns "‎" or "‏", depending on the directionality of the language and whether opposite
is a true or false value.
mw.language:getDurationIntervals
lang:getDurationIntervals( seconds )
lang:getDurationIntervals( seconds, chosenIntervals )
Breaks a duration in seconds into more human-readable units, e.g. 12345 to 3 hours, 25 minutes and 45 seconds, returning the result as a table mapping unit names to numbers.
chosenIntervals
, if given, is a table with values naming the interval units to use in the response. These include 'millennia
', 'centuries
', 'decades
', 'years
', 'weeks
', 'days
', 'hours
', 'minutes
', and 'seconds
'.
Those unit keywords are also the keys used in the response table. Only units with a non-zero value are set in the response, unless the response would be empty in which case the smallest unit is returned with a value of 0.
Бібліотека message (бібліотека повідомлень)
This library is an interface to the localisation messages and the MediaWiki: namespace.
Functions documented as mw.message.name
are available on the global mw.message
table; functions documented as mw.message:name
and msg:name
are methods of a message object (see mw.message.new
).
mw.message.new
mw.message.new( key, ... )
Creates a new message object for the given message key
.
The remaining parameters are passed to the new object's params()
method.
The message object has no properties, but has several methods documented below.
mw.message.newFallbackSequence
mw.message.newFallbackSequence( ... )
Creates a new message object for the given messages (the first one that exists will be used).
The message object has no properties, but has several methods documented below.
mw.message.newRawMessage
mw.message.newRawMessage( msg, ... )
Creates a new message object, using the given text directly rather than looking up an internationalized message. The remaining parameters are passed to the new object's params()
method.
The message object has no properties, but has several methods documented below.
mw.message.rawParam
mw.message.rawParam( value )
Wraps the value so that it will not be parsed as wikitext by msg:parse()
.
mw.message.numParam
mw.message.numParam( value )
Wraps the value so that it will automatically be formatted as by lang:formatNum()
. Note this does not depend on the Language library actually being available.
mw.message.getDefaultLanguage
mw.message.getDefaultLanguage()
Returns a Language object for the default language.
mw.message:params
msg:params( ... )
msg:params( params )
Add parameters to the message, which may be passed as individual arguments or as a sequence table. Parameters must be numbers, strings, or the special values returned by mw.message.numParam() or mw.message.rawParam(). If a sequence table is used, parameters must be directly present in the table; references using the __index metamethod will not work.
Returns the msg
object, to allow for call chaining.
mw.message:rawParams
msg:rawParams( ... )
msg:rawParams( params )
Like :params(), but has the effect of passing all the parameters through mw.message.rawParam() first.
Returns the msg
object, to allow for call chaining.
mw.message:numParams
msg:numParams( ... )
msg:numParams( params )
Like :params(), but has the effect of passing all the parameters through mw.message.numParam() first.
Returns the msg
object, to allow for call chaining.
mw.message:inLanguage
msg:inLanguage( lang )
Specifies the language to use when processing the message. lang
may be a string or a table with a getCode()
method (i.e. a Language object).
The default language is the one returned by mw.message.getDefaultLanguage()
.
Returns the msg
object, to allow for call chaining.
mw.message:useDatabase
msg:useDatabase( bool )
Specifies whether to look up messages in the MediaWiki: namespace (i.e. look in the database), or just use the default messages distributed with MediaWiki.
The default is true
.
Returns the msg
object, to allow for call chaining.
mw.message:plain
msg:plain()
Substitutes the parameters and returns the message wikitext as-is. Template calls and parser functions are intact.
mw.message:exists
msg:exists()
Returns a boolean indicating whether the message key exists.
mw.message:isBlank
msg:isBlank()
Returns a boolean indicating whether the message key has content. Returns true
if the message key does not exist or the message is the empty string.
mw.message:isDisabled
msg:isDisabled()
Returns a boolean indicating whether the message key is disabled. Returns true
if the message key does not exist or if the message is the empty string or the string "-".
Бібліотека site (бібліотека сайтів)
mw.site.currentVersion
A string holding the current version of MediaWiki.
mw.site.scriptPath
The value of $wgScriptPath
.
mw.site.server
The value of $wgServer
.
mw.site.siteName
The value of $wgSitename
.
mw.site.stylePath
The value of $wgStylePath
.
mw.site.namespaces
Table holding data for all namespaces, indexed by number.
The data available is:
- id: Namespace number.
- name: Local namespace name.
- canonicalName: Canonical namespace name.
- displayName: Set on namespace 0, the name to be used for display (since the name is often the empty string).
- hasSubpages: Whether subpages are enabled for the namespace.
- hasGenderDistinction: Whether the namespace has different aliases for different genders.
- isCapitalized: Whether the first letter of pages in the namespace is capitalized.
- isContent: Whether this is a content namespace.
- isIncludable: Whether pages in the namespace can be transcluded.
- isMovable: Whether pages in the namespace can be moved.
- isSubject: Whether this is a subject namespace.
- isTalk: Whether this is a talk namespace.
- defaultContentModel: The default content model for the namespace, as a string.
- aliases: List of aliases for the namespace.
- subject: Reference to the corresponding subject namespace's data.
- talk: Reference to the corresponding talk namespace's data.
- associated:
Reference to the associated namespace's data.
A metatable is also set that allows for looking up namespaces by name (localized or canonical). For example, both mw.site.namespaces[4]
and mw.site.namespaces.Project
will return information about the Project namespace.
mw.site.contentNamespaces
Table holding just the content namespaces, indexed by number. See mw.site.namespaces for details.
mw.site.subjectNamespaces
Table holding just the subject namespaces, indexed by number. See mw.site.namespaces for details.
mw.site.talkNamespaces
Table holding just the talk namespaces, indexed by number. See mw.site.namespaces for details.
mw.site.stats
Table holding site statistics. Available statistics are:
- pages: Number of pages in the wiki.
- articles: Number of articles in the wiki.
- files: Number of files in the wiki.
- edits: Number of edits in the wiki.
- users: Number of users in the wiki.
- activeUsers: Number of active users in the wiki.
- admins: Number of users in group 'sysop' in the wiki.
mw.site.stats.pagesInCategory
mw.site.stats.pagesInCategory( category, which )
- This function is expensive
Gets statistics about the category. If which
has the special value "*
", the result is a table with the following properties:
- all: Total pages, files, and subcategories.
- subcats: Number of subcategories.
- files: Number of files.
- pages: Number of pages.
If which
is one of the above keys ("all", "subcats", "files", "pages"), the result is a number with the corresponding value.
Each new category queried will increment the expensive function count.
mw.site.stats.pagesInNamespace
mw.site.stats.pagesInNamespace( namespace )
Returns the number of pages in the given namespace (specify by number).
mw.site.stats.usersInGroup
mw.site.stats.usersInGroup( group )
Returns the number of users in the given group.
mw.site.interwikiMap
mw.site.interwikiMap( filter )
Returns a table holding data about available interwiki prefixes. If filter
is the string "local", then only data for local interwiki prefixes is returned. If filter
is the string "!local", then only data for non-local prefixes is returned. If no filter is specified, data for all prefixes is returned. A "local" prefix in this context is one that is for the same project. For example, on the English Wikipedia, other-language Wikipedias are considered local, while Wiktionary and such are not.
Keys in the table returned by this function are interwiki prefixes, and the values are subtables with the following properties:
- prefix - the interwiki prefix.
- url - the URL that the interwiki points to. The page name is represented by the parameter $1.
- isProtocolRelative - a boolean showing whether the URL is protocol-relative.
- isLocal - whether the URL is for a site in the current project.
- isCurrentWiki - whether the URL is for the current wiki.
- isTranscludable - whether pages using this interwiki prefix are transcludable. This requires scary transclusion, which is disabled on Wikimedia wikis.
- isExtraLanguageLink - whether the interwiki is listed in
$wgExtraInterlanguageLinkPrefixes
. - displayText - for links listed in $wgExtraInterlanguageLinkPrefixes, this is the display text shown for the interlanguage link. Nil if not specified.
- tooltip -
for links listed in $wgExtraInterlanguageLinkPrefixes, this is the tooltip text shown when users hover over the interlanguage link. Nil if not specified.
Бібліотека text (бібліотека тексту)
The text library provides some common text processing functions missing from the String library and the Ustring library. These functions are safe for use with UTF-8 strings.
mw.text.decode
mw.text.decode( string )
mw.text.decode( string, decodeNamedEntities )
Replaces HTML entities in the string with the corresponding characters.
If boolean decodeNamedEntities
is omitted or false, the only named entities recognized are <
(<), >
(>), &
(&), "
(") and
(the non-breaking space, U+00A0).
Otherwise, the list of HTML5 named entities to recognize is loaded from PHP's get_html_translation_table
function.
Known bugs: Approximately 600 of around 2200 named entities in the HTML5 standard do not get decoded, even when decodeNamedEntities
is used; this includes approximately 40 of around 250 entities which are also included in HTML4.
This occurs because PHP's get_html_translation_table
function returns only one mapping for each character, so for example
is not decoded since PHP returns only →
as the mapping for →
.
→
mw.text.encode
mw.text.encode( string )
mw.text.encode( string, charset )
Replaces characters in a string with HTML entities.
Five characters are replaced with the appropriate named entities: <
, >
, &
, "
and the non-breaking space (U+00A0).
All others are replaced with numeric entities.
If charset
is supplied, it should be a string as appropriate to go inside brackets in a Ustring pattern, i.e. the "set" in [set]
. The default charset contains six characters: <
, >
, &
, "
, '
and the non-breaking space (U+00A0).
mw.text.jsonDecode
mw.text.jsonDecode( string )
mw.text.jsonDecode( string, flags )
Decodes a JSON string. flags
is 0 or a combination (use +
) of the flags mw.text.JSON_PRESERVE_KEYS
and mw.text.JSON_TRY_FIXING
.
Normally JSON's zero-based arrays are renumbered to Lua one-based sequence tables; to prevent this, pass mw.text.JSON_PRESERVE_KEYS
.
To relax certain requirements in JSON, such as no terminal comma in arrays or objects, pass mw.text.JSON_TRY_FIXING
. This is not recommended.
Limitations:
- Decoded JSON arrays may not be Lua sequences if the array contains null values.
- JSON objects will drop keys having null values.
- It is not possible to directly tell whether the input was a JSON array or a JSON object with sequential integer keys.
- A JSON object having sequential integer keys beginning with 1 will decode to the same table structure as a JSON array with the same values, despite these not being at all equivalent, unless
mw.text.JSON_PRESERVE_KEYS
is used.
mw.text.jsonEncode
mw.text.jsonEncode( value )
mw.text.jsonEncode( value, flags )
Encode a JSON string. Errors are raised if the passed value cannot be encoded in JSON. flags
is 0 or a combination (use +
) of the flags mw.text.JSON_PRESERVE_KEYS
and mw.text.JSON_PRETTY
.
Normally Lua one-based sequence tables are encoded as JSON zero-based arrays; when mw.text.JSON_PRESERVE_KEYS
is set in flags
, zero-based sequence tables are encoded as JSON arrays.
Обмеження:
- Empty tables are always encoded as empty arrays (
[]
), not empty objects ({}
). - Sequence tables cannot be encoded as JSON objects without adding a "dummy" element.
- To produce objects or arrays with nil values, a tricky implementation of the
__pairs
metamethod is required. - A Lua table having sequential integer keys beginning with 0 will encode as a JSON array, the same as a Lua table having integer keys beginning with 1, unless
mw.text.JSON_PRESERVE_KEYS
is used. - When both a number and the string representation of that number are used as keys in the same table, behavior is unspecified.
mw.text.killMarkers
mw.text.killMarkers( string )
Removes all MediaWiki strip markers from a string.
mw.text.listToText
mw.text.listToText( list )
mw.text.listToText( list, separator, conjunction )
Joins a list, prose-style. In other words, it's like table.concat()
but with a different separator before the final item.
The default separator is taken from MediaWiki:comma-separator in the wiki's content language, and the default conjunction is MediaWiki:and concatenated with MediaWiki:word-separator.
Examples, using the default values for the messages:
-- Returns the empty string
mw.text.listToText( {} )
-- Returns "1"
mw.text.listToText( { 1 } )
-- Returns "1 and 2"
mw.text.listToText( { 1, 2 } )
-- Returns "1, 2, 3, 4 and 5"
mw.text.listToText( { 1, 2, 3, 4, 5 } )
-- Returns "1; 2; 3; 4 or 5"
mw.text.listToText( { 1, 2, 3, 4, 5 }, '; ', ' or ' )
mw.text.nowiki
mw.text.nowiki( string )
Replaces various characters in the string with HTML entities to prevent their interpretation as wikitext. This includes:
- The following characters:
"
,&
,'
,<
,=
,>
,[
,]
,{
,|
,}
- The following characters at the start of the string or immediately after a newline:
#
,*
,:
,;
, space, tab (\t
)
- Blank lines will have one of the associated newline or carriage return characters escaped
----
at the start of the string or immediately after a newline will have the first-
escaped
__
will have one underscore escaped
://
will have the colon escaped
- A whitespace character following
ISBN
,RFC
, orPMID
will be escaped
mw.text.split
mw.text.split( string, pattern, plain )
Splits the string into substrings at boundaries matching the Ustring pattern pattern
. If plain
is specified and true
, pattern
will be interpreted as a literal string rather than as a Lua pattern (just as with the parameter of the same name for mw.ustring.find()
). Returns a table containing the substrings.
For example, mw.text.split( 'a b\tc\nd', '%s' )
would return a table { 'a', 'b', 'c', 'd' }
.
If pattern
matches the empty string, string
will be split into individual characters.
Note that this function can be over 60 times slower than a reimplementation that is not Unicode-aware, such as the following:
function split(text, pattern, plain)
local ret = {}
local s, l = 1, string.len( text )
while s do
local e, n = string.find( text, pattern, s, plain )
if not e then
ret[#ret+1] = string.sub ( text, s )
s = nil
elseif n < e then
-- Empty separator!
ret[#ret+1] = string.sub ( text, s, e )
if e < l then
s = e + 1
else
s = nil
end
else
ret[#ret+1] = e > s and string.sub( text, s, e - 1 ) or ''
s = n + 1
end
end
return ret
end
mw.text.gsplit
mw.text.gsplit( string, pattern, plain )
Returns an iterator function that will iterate over the substrings that would be returned by the equivalent call to mw.text.split()
.
Note that this function can be over 60 times slower than a reimplementation that is not Unicode-aware, such as the following:
function gsplit( text, pattern, plain )
local s, l = 1, string.len( text )
return function ()
if s then
local e, n = string.find( text, pattern, s, plain )
local ret
if not e then
ret = string.sub( text, s )
s = nil
elseif n < e then
-- Empty separator!
ret = string.sub( text, s, e )
if e < l then
s = e + 1
else
s = nil
end
else
ret = e > s and string.sub( text, s, e - 1 ) or ''
s = n + 1
end
return ret
end
end, nil, nil
end
mw.text.tag
mw.text.tag( name, attrs, content )
mw.text.tag{ name = string, attrs = table, content = string|false }
- Note the use of named arguments.
Generates an HTML-style tag for name
.
If attrs
is given, it must be a table with string keys. String and number values are used as the value of the attribute; boolean true
results in the key being output as an HTML5 valueless parameter; boolean false
skips the key entirely; and anything else is an error.
If content
is not given (or is nil), only the opening tag is returned. If content
is boolean false
, a self-closed tag is returned. Otherwise it must be a string or number, in which case that content is enclosed in the constructed opening and closing tag. Note the content is not automatically HTML-encoded; use mw.text.encode() if needed.
For properly returning extension tags such as <ref>
, use frame:extensionTag() instead.
mw.text.trim
mw.text.trim( string )
mw.text.trim( string, charset )
Remove whitespace or other characters from the beginning and end of a string.
If charset
is supplied, it should be a string as appropriate to go inside brackets in a Ustring pattern, i.e. the "set" in [set]
. The default charset is ASCII whitespace, %s
, which is equivalent to "\t\r\n\f\v "
.
mw.text.truncate
mw.text.truncate( text, length )
mw.text.truncate( text, length, ellipsis )
mw.text.truncate( text, length, ellipsis, adjustLength )
Truncates text
to the specified length in code points, adding ellipsis
if truncation was performed. If length is positive, the end of the string will be truncated; if negative, the beginning will be removed. If adjustLength
is given and true
, the resulting string including ellipsis will not be longer than the specified length.
The default value for ellipsis
is taken from MediaWiki:ellipsis in the wiki's content language.
Examples, using the default "..." ellipsis:
-- Returns "foobarbaz"
mw.text.truncate( "foobarbaz", 9 )
-- Returns "fooba..."
mw.text.truncate( "foobarbaz", 5 )
-- Returns "...arbaz"
mw.text.truncate( "foobarbaz", -5 )
-- Returns "foo..."
mw.text.truncate( "foobarbaz", 6, nil, true )
-- Returns "foobarbaz", because that's shorter than "foobarba..."
mw.text.truncate( "foobarbaz", 8 )
mw.text.unstripNoWiki
mw.text.unstripNoWiki( string )
Replaces MediaWiki <nowiki> strip markers with the corresponding text. Other types of strip markers are not changed.
mw.text.unstrip
mw.text.unstrip( string )
Equivalent to mw.text.killMarkers( mw.text.unstripNoWiki( string ) )
.
This no longer reveals the HTML behind special page transclusion, <ref> tags, and so on as it did in earlier versions of Scribunto.
Title library
mw.title.equals
mw.title.equals( a, b )
Test for whether two titles are equal. Note that fragments are ignored in the comparison.
mw.title.compare
mw.title.compare( a, b )
Returns -1, 0, or 1 to indicate whether the title a
is less than, equal to, or greater than title b
.
This compares titles by interwiki prefix (if any) as strings, then by namespace number, then by the unprefixed title text as a string. These string comparisons use Lua's standard <
operator.
mw.title.getCurrentTitle
mw.title.getCurrentTitle()
Returns the title object for the current page.
mw.title.new
mw.title.new( text, namespace )
mw.title.new( ID )
- This function is expensive when called with an ID
Creates a new title object.
If a number ID
is given, an object is created for the title with that page_id. The title referenced will be counted as linked from the current page. If the page_id does not exist, returns nil. The expensive function count will be incremented if the title object created is not for a title that has already been loaded.
If a string text
is given instead, an object is created for that title (even if the page does not exist). If the text string does not specify a namespace, namespace
(which may be any key found in mw.site.namespaces
) will be used. If the text is not a valid title, nil is returned.
mw.title.makeTitle
mw.title.makeTitle( namespace, title, fragment, interwiki )
Creates a title object with title title
in namespace namespace
, optionally with the specified fragment
and interwiki
prefix. namespace
may be any key found in mw.site.namespaces
. If the resulting title is not valid, returns nil.
Note that, unlike mw.title.new()
, this method will always apply the specified namespace. For example, mw.title.makeTitle( 'Template', 'Module:Foo' )
will create an object for the page Template:Module:Foo, while mw.title.new( 'Module:Foo', 'Template' )
will create an object for the page Module:Foo.
Note also that functionality for interwiki titles is limited to interwiki
/ isExternal
/ isLocal
and URL-related methods; other methods might not behave as expected.
Title objects
A title object has a number of properties and methods. Most of the properties are read-only.
Note that fields ending with text
return titles as string values whereas the fields ending with title
return title objects.
- id: The page_id.
0
if the page does not exist.
This may be expensive.
- interwiki: The interwiki prefix, or the empty string if none.
- namespace: The namespace number.
- fragment: The fragment (aka section/anchor linking), or the empty string. May be assigned.
- nsText: The text of the namespace for the page.
- subjectNsText: The text of the subject namespace for the page.
- talkNsText: The text of the talk namespace for the page, or
nil
if this title cannot have a talk page. (added in MediaWiki 1.42.0-wmf.15, refs T180911)
- text: The title of the page, without the namespace or interwiki prefixes.
- prefixedText: The title of the page, with the namespace and interwiki prefixes.
- fullText: The title of the page, with the namespace and interwiki prefixes and the fragment. Interwiki is not returned if equal to the current.
- rootText: If this is a subpage, the title of the root page without prefixes. Otherwise, the same as
title.text
.
- baseText: If this is a subpage, the title of the page it is a subpage of without prefixes. Otherwise, the same as
title.text
.
- subpageText: If this is a subpage, just the subpage name. Otherwise, the same as
title.text
.
- canTalk: Whether the page for this title could have a talk page.
- exists: Whether the page exists. Alias for
file.exists
for Media-namespace titles. For File-namespace titles this checks the existence of the file description page, not the file itself. This may be expensive.
- file, fileExists: See #File metadata below.
- isContentPage: Whether this title is in a content namespace.
- isExternal: Whether this title has an interwiki prefix.
- isLocal: Whether this title is in this project. For example, on the English Wikipedia, any other Wikipedia is considered "local" while Wiktionary and such are not.
- isRedirect: Whether this is the title for a page that is a redirect. This may be expensive.
- isSpecialPage: Whether this is the title for a possible special page (i.e. a page in the Special: namespace).
- isSubpage: Whether this title is a subpage of some other title.
- isTalkPage: Whether this is a title for a talk page.
- isSubpageOf( title2 ): Whether this title is a subpage of the given title.
- inNamespace( ns ): Whether this title is in the given namespace. Namespaces may be specified by anything that is a key found in
mw.site.namespaces
.
- inNamespaces( ... ): Whether this title is in any of the given namespaces. Namespaces may be specified by anything that is a key found in
mw.site.namespaces
.
- hasSubjectNamespace( ns ): Whether this title's subject namespace is in the given namespace. Namespaces may be specified by anything that is a key found in
mw.site.namespaces
.
- contentModel: The content model for this title, as a string. This may be expensive.
- basePageTitle: The same as
mw.title.makeTitle( title.namespace, title.baseText )
.
- rootPageTitle: The same as
mw.title.makeTitle( title.namespace, title.rootText )
.
- talkPageTitle: The same as
mw.title.makeTitle( mw.site.namespaces[title.namespace].talk.id, title.text )
, ornil
if this title cannot have a talk page.
- subjectPageTitle: The same as
mw.title.makeTitle( mw.site.namespaces[title.namespace].subject.id, title.text )
.
- redirectTarget: Returns a title object of the target of the redirect page if the page is a redirect and the page exists, returns
false
otherwise.
- protectionLevels: The page's protection levels. This is a table with keys corresponding to each action (e.g.,
"edit"
and"move"
). The table values are arrays, the first item of which is a string containing the protection level. If the page is unprotected, either the table values or the array items will benil
. This is expensive.
- cascadingProtection: The cascading protections applicable to the page. This is a table with keys
"restrictions"
(itself a table with keys likeprotectionLevels
has) and"sources"
(an array listing titles where the protections cascade from). If no protections cascade to the page,"restrictions"
and"sources"
will be empty. This is expensive.
- categories: (since v1.43.0-wmf.18) The list of categories used on the page. This is expensive
- subPageTitle( text ): The same as
mw.title.makeTitle( title.namespace, title.text .. '/' .. text )
.
- partialUrl(): Returns
title.text
encoded as it would be in a URL.
- fullUrl( query, proto ): Returns the full URL (with optional query table/string) for this title. proto may be specified to control the scheme of the resulting url:
"http"
,"https"
,"relative"
(the default), or"canonical"
.
- localUrl( query ): Returns the local URL (with optional query table/string) for this title.
- canonicalUrl( query ): Returns the canonical URL (with optional query table/string) for this title.
- content or getContent(): Returns the (unparsed) content of the page, or
nil
if there is no page. The page will be recorded as a transclusion.
- pageLang: A language object for the title's page content language, which defaults to the wiki's content language. This is expensive.
Title objects may be compared using relational operators. tostring( title )
will return title.prefixedText
.
Note that accessing any expensive field on a title object records a "link" to the page (as shown on Special:WhatLinksHere, for example). Using the title object's getContent()
method or accessing the redirectTarget
field records it as file
or fileExists
fields records it as a "посилання на файл".
File metadata
Title objects representing a page in the File or Media namespace will have a property called file
. This is expensive. This is a table, structured as follows:
- exists: Whether the file exists. It will be recorded as an image usage. The
fileExists
property on a Title object exists for backwards compatibility reasons and is an alias for this property. If this isfalse
, all other file properties will benil
.
- width: The width of the file. If the file contains multiple pages, this is the width of the first page.
- height: The height of the file. If the file contains multiple pages, this is the height of the first page.
- pages: If the file format supports multiple pages, this is a table containing tables for each page of the file; otherwise, it is
nil
. The # operator can be used to get the number of pages in the file. Each individual page table contains a width and height property.
- size: The size of the file in bytes.
- mimeType: The MIME type of the file.
- length: The length (duration) of the media file in seconds. Zero for media types which do not support length.
Expensive properties
The properties id
, isRedirect
, exists
, and contentModel
require fetching data about the title from the database. For this reason, the expensive function count is incremented the first time one of them is accessed for a page other than the current page. Subsequent accesses of any of these properties for that page will not increment the expensive function count again.
Other properties marked as expensive will always increment the expensive function count the first time they are accessed for a page other than the current page.
URI library
mw.uri.encode
mw.uri.encode( string, enctype )
Percent-encodes the string. The default type, "QUERY"
, encodes spaces using '+' for use in query strings; "PATH"
encodes spaces as %20; and "WIKI"
encodes spaces as '_'.
Note that the "WIKI" format is not entirely reversible, as both spaces and underscores are encoded as '_'.
mw.uri.decode
mw.uri.decode( string, enctype )
Percent-decodes the string. The default type, "QUERY"
, decodes '+' to space; "PATH"
does not perform any extra decoding; and "WIKI"
decodes '_' to space.
mw.uri.anchorEncode
mw.uri.anchorEncode( string )
Encodes a string for use in a MediaWiki URI fragment.
mw.uri.buildQueryString
mw.uri.buildQueryString( table )
Encodes a table as a URI query string. Keys should be strings; values may be strings or numbers, sequence tables, or boolean false.
mw.uri.parseQueryString
mw.uri.parseQueryString( s, i, j )
Decodes the query string s
to a table. Keys in the string without values will have a value of false
; keys repeated multiple times will have sequence tables as values; and others will have strings as values.
The optional numerical arguments i
and j
can be used to specify a substring of s
to be parsed, rather than the entire string. i
is the position of the first character of the substring, and defaults to 1. j
is the position of the last character of the substring, and defaults to the length of the string. Both i
and j
can be negative, as in string.sub.
mw.uri.canonicalUrl
mw.uri.canonicalUrl( page, query )
Returns a URI object for the canonical URL for a page, with optional query string/table.
mw.uri.fullUrl
mw.uri.fullUrl( page, query )
Returns a URI object for the full URL for a page, with optional query string/table.
mw.uri.localUrl
mw.uri.localUrl( page, query )
Returns a URI object for the local URL for a page, with optional query string/table.
mw.uri.new
mw.uri.new( string )
Constructs a new URI object for the passed string or table. See the description of URI objects for the possible fields for the table.
mw.uri.validate
mw.uri.validate( table )
Validates the passed table (or URI object). Returns a boolean indicating whether the table was valid, and on failure a string explaining what problems were found.
URI object
The URI object has the following fields, some or all of which may be nil:
- protocol: String protocol/scheme
- user: String user
- password: String password
- host: String host name
- port: Integer port
- path: String path
- query: A table, as from mw.uri.parseQueryString
- fragment: String fragment.
The following properties are also available:
- userInfo: String user and password
- hostPort: String host and port
- authority: String user, password, host, and port
- queryString: String version of the query table
- relativePath: String path, query string, and fragment
tostring()
will give the URI string.
Methods of the URI object are:
mw.uri:parse
uri:parse( string )
Parses a string into the current URI object. Any fields specified in the string will be replaced in the current object; fields not specified will keep their old values.
mw.uri:clone
uri:clone()
Makes a copy of the URI object.
mw.uri:extend
uri:extend( parameters )
Merges the parameters table into the object's query table.
Ustring library
The ustring library is intended to be a direct reimplementation of the standard String library, except that the methods operate on characters in UTF-8 encoded strings rather than bytes.
Most functions will raise an error if the string is not valid UTF-8; exceptions are noted.
mw.ustring.maxPatternLength
The maximum allowed length of a pattern, in bytes.
mw.ustring.maxStringLength
The maximum allowed length of a string, in bytes.
mw.ustring.byte
mw.ustring.byte( s, i, j )
Returns individual bytes; identical to string.byte().
mw.ustring.byteoffset
mw.ustring.byteoffset( s, l, i )
Returns the byte offset of a character in the string. The default for both l
and i
is 1. i
may be negative, in which case it counts from the end of the string.
The character at l
== 1 is the first character starting at or after byte i
; the character at l
== 0 is the first character starting at or before byte i
. Note this may be the same character. Greater or lesser values of l
are calculated relative to these.
mw.ustring.char
mw.ustring.char( ... )
Much like string.char(), except that the integers are Unicode codepoints rather than byte values.
local value = mw.ustring.char( 0x41f, 0x440, 0x438, 0x432, 0x435, 0x442, 0x21 ) -- value is now 'Привет!'
mw.ustring.codepoint
mw.ustring.codepoint( s, i, j )
Much like string.byte(), except that the return values are codepoints and the offsets are characters rather than bytes.
mw.ustring.find
mw.ustring.find( s, pattern, init, plain )
Much like string.find(), except that the pattern is extended as described in Ustring patterns and the init
offset is in characters rather than bytes.
mw.ustring.format
mw.ustring.format( format, ... )
Identical to string.format(). Widths and precisions for strings are expressed in bytes, not codepoints.
mw.ustring.gcodepoint
mw.ustring.gcodepoint( s, i, j )
Returns three values for iterating over the codepoints in the string. i
defaults to 1, and j
to -1. This is intended for use in the iterator form of for
:
for codepoint in mw.ustring.gcodepoint( s ) do
-- block
end
mw.ustring.gmatch
mw.ustring.gmatch( s, pattern )
Much like string.gmatch(), except that the pattern is extended as described in Ustring patterns.
Known bug - When used with a pattern which can match the empty string, the function will get stuck in an infinite loop. For example, the following loop never terminates:
for capture in mw.ustring.gmatch( "foo bar", ".*" ) do
-- block
end
mw.ustring.gsub
mw.ustring.gsub( s, pattern, repl, n )
Much like string.gsub(), except that the pattern is extended as described in Ustring patterns.
Known bugs: When repl
is a table, it is possible to use numbers as keys instead of strings (e.g. to replace instances of
in a string, the value at key "5"
or [5]
would be used); as such, the output is not predictable if they have different (non-nil) values.
["5"]
This is not an issue for string.gsub(), which ignores any numbers as keys.
mw.ustring.isutf8
mw.ustring.isutf8( string )
Returns true
if the string is valid UTF-8, false
if not.
mw.ustring.len
mw.ustring.len( string )
Returns the length of the string in codepoints, or nil if the string is not valid UTF-8.
See string.len() for a similar function that uses byte length rather than codepoints.
mw.ustring.lower
mw.ustring.lower( string )
Much like string.lower(), except that all characters with lowercase to uppercase definitions in Unicode are converted.
If the Language library is also loaded, this will instead call lc() on the default language object.
mw.ustring.match
mw.ustring.match( s, pattern, init )
Much like string.match(), except that the pattern is extended as described in Ustring patterns and the init
offset is in characters rather than bytes.
mw.ustring.rep
mw.ustring.rep( string, n )
Identical to string.rep().
mw.ustring.sub
mw.ustring.sub( s, i, j )
Much like string.sub(), except that the offsets are characters rather than bytes.
mw.ustring.toNFC
mw.ustring.toNFC( string )
Converts the string to Normalization Form C (also known as Normalization Form Canonical Composition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFD
mw.ustring.toNFD( s )
Converts the string to Normalization Form D (also known as Normalization Form Canonical Decomposition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFKC
mw.ustring.toNFKC( s )
Converts the string to Normalization Form KC (also known as Normalization Form Compatibility Composition). Returns nil if the string is not valid UTF-8.
mw.ustring.toNFKD
mw.ustring.toNFKD( s )
Converts the string to Normalization Form KD (also known as Normalization Form Compatibility Decomposition). Returns nil if the string is not valid UTF-8.
mw.ustring.upper
mw.ustring.upper( s )
Much like string.upper(), except that all characters with uppercase to lowercase definitions in Unicode are converted.
If the Language library is also loaded, this will instead call uc() on the default language object.
Ustring patterns
Patterns in the ustring functions use the same syntax as the String library patterns. The major difference is that the character classes are redefined in terms of Unicode character properties:
%a
: represents all characters with General Category "Letter".
%c
: represents all characters with General Category "Control".
%d
: represents all characters with General Category "Number, decimal digit".
%l
: represents all characters with General Category "Lowercase Letter".
%p
: represents all characters with General Category "Punctuation".
%s
: represents all characters with General Category "Separator", plus tab, linefeed, carriage return, vertical tab, and form feed.
%u
: represents all characters with General Category "Uppercase Letter".
%w
: represents all characters with General Category "Letter" or "Decimal Number".
%x
: adds fullwidth character versions of the hex digits.
Like in String library patterns, %A
, %C
, %D
, %L
, %P
, %S
, %U
, %W
та %X
here represent the complementary set ("all characters without given General Category").
In all cases, characters are interpreted as Unicode characters instead of bytes, so ranges such as [0-9]
, patterns such as %b«»
, and quantifiers applied to multibyte characters will work correctly. Empty captures will capture the position in code points rather than bytes.
Known limitations: Unlike String library patterns, Ustring library patterns have a maximum length of 10,000 bytes. If the pattern exceeds this length, then the Ustring function will throw an error. Because the String library has its own maximum of 32 captures (unlike the Ustring library), it is therefore impossible to use a pattern which exceeds both limits, as it will be incompatible with both libraries.
Note: 9 ASCII characters, $
, +
, <
, =
, >
, ^
, `
, |
, ~
, can be matched by %p
in the string library but not in the ustring library, as Unicode classifies them as Symbols rather than Punctuation.
Loadable libraries
These libraries are not included by default, but if needed may be loaded using require()
.
bit32
This emulation of the Lua 5.2 bit32
library may be loaded using:
bit32 = require( 'bit32' )
The bit32 library provides bitwise operations on unsigned 32-bit integers. Input numbers are truncated to integers (in an unspecified manner) and reduced modulo 232 so the value is in the range 0 to 232−1; return values are also in this range.
When bits are numbered (as in bit32.extract()), 0 is the least-significant bit (the one with value 20) and 31 is the most-significant (the one with value 231).
bit32.band
bit32.band( ... )
Returns the bitwise AND of its arguments: the result has a bit set only if that bit is set in all of the arguments.
If given zero arguments, the result has all bits set.
bit32.bnot
bit32.bnot( x )
Returns the bitwise complement of x
.
bit32.bor
bit32.bor( ... )
Returns the bitwise OR of its arguments: the result has a bit set if that bit is set in any of the arguments.
If given zero arguments, the result has all bits clear.
bit32.btest
bit32.btest( ... )
Equivalent to bit32.band( ... ) ~= 0
bit32.bxor
bit32.bxor( ... )
Returns the bitwise XOR of its arguments: the result has a bit set if that bit is set in an odd number of the arguments.
If given zero arguments, the result has all bits clear.
bit32.extract
bit32.extract( n, field, width )
Extracts width
bits from n
, starting with bit field
. Accessing bits outside of the range 0 to 31 is an error.
If not specified, the default for width
is 1.
bit32.replace
bit32.replace( n, v, field, width )
Replaces width
bits in n
, starting with bit field
, with the low width
bits from v
. Accessing bits outside of the range 0 to 31 is an error.
If not specified, the default for width
is 1.
bit32.lshift
bit32.lshift( n, disp )
Returns the number n
shifted disp
bits to the left. This is a logical shift: inserted bits are 0. This is generally equivalent to multiplying by 2disp
.
Note that a displacement over 31 will result in 0.
bit32.rshift
bit32.rshift( n, disp )
Returns the number n
shifted disp
bits to the right. This is a logical shift: inserted bits are 0. This is generally equivalent to dividing by 2disp
.
Note that a displacement over 31 will result in 0.
bit32.arshift
bit32.arshift( n, disp )
Returns the number n
shifted disp
bits to the right. This is an arithmetic shift: if disp
is positive, the inserted bits will be the same as bit 31 in the original number.
Note that a displacement over 31 will result in 0 or 4294967295.
bit32.lrotate
bit32.lrotate( n, disp )
Returns the number n
rotated disp
bits to the left.
Note that rotations are equivalent modulo 32: a rotation of 32 is the same as a rotation of 0, 33 is the same as 1, and so on.
bit32.rrotate
bit32.rrotate( n, disp )
Returns the number n
rotated disp
bits to the right.
Note that rotations are equivalent modulo 32: a rotation of 32 is the same as a rotation of 0, 33 is the same as 1, and so on.
libraryUtil
This library contains methods useful when implementing Scribunto libraries. It may be loaded using:
libraryUtil = require( 'libraryUtil' )
libraryUtil.checkType
libraryUtil.checkType( name, argIdx, arg, expectType, nilOk )
Raises an error if type( arg )
does not match expectType
. In addition, no error will be raised if arg
is nil and nilOk
is true.
name
is the name of the calling function, and argIdx
is the position of the argument in the argument list. These are used in formatting the error message.
libraryUtil.checkTypeMulti
libraryUtil.checkTypeMulti( name, argIdx, arg, expectTypes )
Raises an error if type( arg )
does not match any of the strings in the array expectTypes
.
This is for arguments that have more than one valid type.
libraryUtil.checkTypeForIndex
libraryUtil.checkTypeForIndex( index, value, expectType )
Raises an error if type( value )
does not match expectType
.
This is intended for use in implementing a __newindex
metamethod.
libraryUtil.checkTypeForNamedArg
libraryUtil.checkTypeForNamedArg( name, argName, arg, expectType, nilOk )
Raises an error if type( arg )
does not match expectType
. In addition, no error will be raised if arg
is nil and nilOk
is true.
This is intended to be used as an equivalent to libraryUtil.checkType()
in methods called using Lua's "named argument" syntax, func{ name = value }
.
libraryUtil.makeCheckSelfFunction
libraryUtil.makeCheckSelfFunction( libraryName, varName, selfObj, selfObjDesc )
This is intended for use in implementing "methods" on object tables that are intended to be called with the obj:method()
syntax. It returns a function that should be called at the top of these methods with the self
argument and the method name, which will raise an error if that self
object is not selfObj
.
This function will generally be used in a library's constructor function, something like this:
function myLibrary.new()
local obj = {}
local checkSelf = libraryUtil.makeCheckSelfFunction( 'myLibrary', 'obj', obj, 'myLibrary object' )
function obj:method()
checkSelf( self, 'method' )
end
function obj:method2()
checkSelf( self, 'method2' )
end
return obj
end
luabit
The luabit library modules "bit" and "hex" may be loaded using:
bit = require( 'luabit.bit' )
hex = require( 'luabit.hex' )
Note that the bit32 library contains the same operations as "luabit.bit", and the operations in "luabit.hex" may be performed using string.format()
and tonumber()
.
The luabit module "noki" is not available, as it is entirely useless in Scribunto. The luabit module "utf8" is also not available, as it was considered redundant to the Ustring library.
strict
The strict library is not a normal library; it causes an error to be raised whenever a new variable is used that is not explicitly scoped as a local variable (e.g., global variable assignment references). This functionality is typically enabled by loading at the top of a module using:
require( 'strict' )
On many Wikimedia wikis this was formerly implemented in Module:No globals
, which was replaced via phab:T209310. It is in part derived from strict.lua.
ustring
The pure-Lua backend to the Ustring library may be loaded using:
ustring = require( 'ustring' )
In all cases the Ustring library (mw.ustring
) should be used instead, as that replaces many of the slower and more memory-intensive operations with callbacks into PHP code.
Extension libraries
Some MediaWiki extensions provide additional Scribunto libraries. These are also located in the table mw
, usually in the table mw.ext
, however, they are only present when certain extensions are installed (in addition to the Scribunto extension itself).
Such extensions use Scribunto provided hooks:
Writing Scribunto libraries provides information on how such libraries can be developed to provide Lua interfaces for MediaWiki extensions.
mw.wikibase
Клієнт Wikibase provides access to localizable structured data, most notably Wikidata. See docs_topics_lua.html and Extension:Wikibase Client/Lua .
mw.wikibase.lexeme
WikibaseLexeme provides access to Wikibase Lexeme entities. This is supported by Wikidata:Lexicographical data. See md_docs_2topics_2lua.html and Extension:WikibaseLexeme/Lua .
mw.wikibase.mediainfo
WikibaseMediaInfo provides access to Wikibase MediaInfo entities. See WikibaseMediaInfo/Lua . This is supported by Structured Data on Commons. See Structured data/Lua.
mw.bcmath
BCmath provides arbitrary-precision arithmetic to Lua modules. See BCmath documentation via "LDoc" link at BCmath § Usage.
mw.smw
Semantic Scribunto provides native Scribunto support for the Semantic MediaWiki extension.
mw.ext.data
JsonConfig provides access to localizable tabular and map data. See JsonConfig/Tabular . Tabular Data and GeoJSON Map Data is supported in the "Data:" namespace at Commons.
mw.ext.data.get( pagename )
mw.ext.cargo
Cargo provides a means to query its data store from Lua. See Extension:Cargo/Other features#Lua support .
mw.ext.cattools
CategoryToolbox provides a means to check from Lua if a certain page belongs to a category. Is is experimental and not enabled on public WikiMedia wikis.
mw.ext.FlaggedRevs
FlaggedRevs provides a means to access the stability settings of a page from Lua.
mw.ext.TitleBlacklist
TitleBlacklist provides a means to test and obtain information about blacklisted page naming entries from Lua.
mw.ext.ParserFunctions
ParserFunctions provides a means from Lua to evaluate expressions in the same way as its PHP-based parser function #expr
.
mw.ext.proofreadPage
Proofread Page provides access to Index and Page namespaces. See Extension:Proofread Page/Lua reference . This is supported by Wikisource:ProofreadPage. See Довідка:Розширення:ProofreadPage .
mw.ext.articlePlaceholder
ArticlePlaceholder provides a means to override default Wikibase renderings from Lua. See Extension:ArticlePlaceholder/Module:AboutTopic .
mw.ext.externalData
ExternalData provides a means to get structured data from Internet from Lua. See Extension:External Data/Lua .
mw.ext.UnlinkedWikibase
See UnlinkedWikibase
mw.ext.UnlinkedWikibase.getEntity( id )
mw.ext.UnlinkedWikibase.query( sparql )
mw.ext.seo
WikiSEO provides a means to set SEO Data for the current page. See Extension:WikiSEO#Usage in lua modules.
mw.slots
WSSlots provides a number of Lua functions for working with MCR slots:
mw.slots.slotContent(slotName, pageName)
mw.slots.slotTemplates(slotName, pageName)
(deprecated)mw.slots.slotContentModel(slotName, pageName)
mw.slots.slotData(slotName, pageName)
Differences from standard Lua
Changed functions
The following functions have been modified:
- setfenv()
- getfenv()
- May not be available, depending on the configuration. If available, attempts to access parent environments will fail.
- getmetatable()
- Works on tables only to prevent unauthorized access to parent environments.
- tostring()
- Pointer addresses of tables and functions are not provided. This is to make memory corruption vulnerabilities more difficult to exploit.
- pairs()
- ipairs()
- Support for the __pairs and __ipairs metamethods (added in Lua 5.2) has been added.
- pcall()
- xpcall()
- Certain internal errors cannot be intercepted.
- require()
- Can fetch certain built-in modules distributed with Scribunto, as well as modules present in the Module namespace of the wiki. To fetch wiki modules, use the full page name including the namespace. Cannot otherwise access the local filesystem.
Removed functions and packages
The following packages are mostly removed. Only those functions listed are available:
- package.*
- Filesystem and C library access has been removed. Available functions and tables are:
- package.loaded
- package.preload
- package.loaders
- Loaders which access the local filesystem or load C libraries are not present. A loader for Module-namespace pages is added.
- package.seeall()
- os.*
- There are some insecure functions in here, such as os.execute(), which can't be allowed. Available functions are:
- debug.*
- Most of the functions are insecure. Available functions are:
The following functions and packages are not available:
- collectgarbage()
- module()
- coroutine.*
- No application is known for us, so it has not been reviewed for security.
- dofile()
- loadfile()
- io.*, file.*
- Allows local filesystem access, which is insecure.
- load()
- loadstring()
- These were omitted to allow for static analysis of the Lua source code. Also, allowing these would allow Lua code to be added directly to article and template pages, which was not desired for usability reasons.
- print()
- This was discussed on wikitech-l and it was decided that it should be omitted in favour of return values, to improve code quality. If necessary, mw.log() may be used to output information to the debug console.
- string.dump()
- May expose private data from parent environments.
Additional caveats
- Referential data structures
- Circular data structures and data structures where the same node may be reached by more than one path cannot be correctly sent to PHP.
Attempting to do so will cause undefined behavior. This includes (but is not limited to) returning such data structures from the module called by {{#invoke:}}
and passing such data structures as parameters to Scribunto library functions that are implemented as callbacks into PHP.
Such data structures may be used freely within Lua, including as the return values of modules loaded with mw.loadData()
.
Writing Scribunto libraries
This information is useful to developers writing additional Scribunto libraries, whether for inclusion in Scribunto itself or for providing an interface for their own extensions.
A Scribunto library will generally consist of five parts:
- The PHP portion of the library.
- The Lua portion of the library.
- The PHP portion of the test cases.
- The Lua portion of the test cases.
- The documentation.
Existing libraries serve as a good example.
Library
The PHP portion of the library is a class that must extend Scribunto_LuaLibraryBase
. See the documentation for that class for implementation details. In the Scribunto extension, this file should be placed in engines/LuaCommon/NameLibrary.php
, and a mapping added to Scribunto_LuaEngine::$libraryClasses
. Other extensions should use the ScribuntoExternalLibraries hook. In either case, the key should match the Lua module name ("mw.name" for libraries in Scribunto, or "mw.ext.name" for extension libraries).
The Lua portion of the library sets up the table containing the functions that can be called from Lua modules. In the Scribunto extension, the file should be placed in engines/LuaCommon/lualib/mw.name.lua
. This file should generally include boilerplate something like this:
local object = {}
local php
function object.setupInterface( options )
-- Remove setup function
object.setupInterface = nil
-- Copy the PHP callbacks to a local variable, and remove the global
php = mw_interface
mw_interface = nil
-- Do any other setup here
-- Install into the mw global
mw = mw or {}
mw.ext = mw.ext or {}
mw.ext.NAME = object
-- Indicate that we're loaded
package.loaded['mw.ext.NAME'] = object
end
return object
The module in engines/LuaCommon/lualib/libraryUtil.lua
(load this with local util = require 'libraryUtil'
) contains some functions that may be helpful.
Be sure to run the Scribunto test cases with your library loaded, even if your library doesn't itself provide any test cases. The standard test cases include tests for things like libraries adding unexpected global variables. Also, if the library is loaded with PHP, any upvalues that its Lua functions have will not be reset between #invoke's. Care must be taken to ensure that modules can't abuse this to transfer information between #invoke's.
Test cases
The Scribunto extension includes a base class for test cases, Scribunto_LuaEngineTestBase
, which will run the tests against both the LuaSandbox and LuaStandalone engines.
The library's test case should extend this class, and should not override static function suite()
.
In the Scribunto extension, the test case should be in tests/engines/LuaCommon/NameLibraryTest.php
and added to the array in ScribuntoHooks::unitTestsList()
(in common/Hooks.php
); extensions should add the test case in their own UnitTestsList
hook function, probably conditional on whether $wgAutoloadClasses['Scribunto_LuaEngineTestBase']
is set.
Most of the time, all that is needed to make the test case is this:
class ClassNameTest extends Scribunto_LuaEngineTestBase { protected static $moduleName = 'ClassNameTest'; function getTestModules() { return parent::getTestModules() + array( 'ClassNameTest' => __DIR__ . '/ClassNameTests.lua'; ); } }
This will load the file ClassNameTests.lua
as if it were the page "Module:ClassNameTests", expecting it to return an object with the following properties:
- count: Integer, number of tests
- provide( n ): Function that returns three values:
n
, the name of testn
, and a string that is the expected output for testn
. - run( n ): Function that runs test
n
and returns one string.
If getTestModules()
is declared as shown, "Module:TestFramework" is available which provides many useful helper methods. If this is used, ClassNameTests.lua
would look something like this:
local testframework = require 'Module:TestFramework'
return testframework.getTestProvider( {
-- Tests go here
} )
Each test is itself a table, with the following properties:
- name: The name of the test.
- func: The function to execute.
- args: Optional table of arguments to pass to the function.
- expect: Results to expect.
- type: Optional "type" of the test, default is "Normal".
The type controls the format of expect
and how func
is called. Included types are:
- Normal:
expect
is a table of return values, or a string if the test should raise an error.func
is simply called. - Iterator:
expect
is a table of tables of return values.func
is called as with an iterated for loop, and each iteration's return values are accumulated. - ToString: Like "Normal", except each return value is passed through
tostring()
.
Test cases in another extension
There are (at least) two ways to run PHPUnit tests:
- Run phpunit against core, allowing the tests/phpunit/suites/ExtensionsTestSuite.php to find the extension's tests using the UnitTestsList hook.
If your extension's test class names all contain a unique component (e.g. the extension's name), the --filter
option may be used to run only your extension's tests.
- Run phpunit against the extension directory, where it will pick up any file ending in "Test.php".
Either of these will work fine if Scribunto is loaded in LocalSettings.php. And it is easy for method #1 to work if Scribunto is not loaded, as the UnitTestsList hook can easily be written to avoid returning the Scribunto test when $wgAutoloadClasses[ 'Scribunto_LuaEngineTestBase' ]
is not set.
But Jenkins uses method #2. For Jenkins to properly run the tests, you will need to add Scribunto as a dependency for your extension. See Gerrit change 56570 for an example of how this is done.
If for some reason you need the tests to be able to run using method #2 without Scribunto loaded, one workaround is to add this check to the top of your unit test file:
if ( !isset( $GLOBALS['wgAutoloadClasses']['Scribunto_LuaEngineTestBase'] ) ) {
return;
}
Documentation
Modules included in Scribunto should include documentation in the Scribunto libraries section above. Extension libraries should include documentation in a subpage of their own extension page, and link to that documentation from the Extension libraries subsection above.
See also
License
This manual is derived from the Lua 5.1 reference manual, which is available under the MIT license.
Copyright © 1994–2012 Lua.org, PUC-Rio. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This derivative manual may also be copied under the terms of the same license.