Fandom Developers Wiki
Advertisement

Documentation for Fandom's backported version of Scribunto. Mostly based on the MediaWiki version of the Lua reference manual around the time the extension became incompatible with MW 1.20.

Introduction

This manual documents Lua as it is used in MediaWiki with the Scribunto extension. Some parts are derived from the Lua 5.1 reference manual, which is available under an MIT-style 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.

Getting started

On a MediaWiki wiki with Scribunto enabled, create a page with a title starting with "Module:", for example "Module:Bananas". Into this new page, copy the following text:

local p = {}

function p.hello( frame )
    return "Hello, world!"
end

return p

Save that, then on another (non-module) page, write:

{{#invoke:Bananas|hello}}

Except that you should replace "Bananas" with whatever you called your module. This will call the "hello" function exported from that module. The {{#invoke:Bananas|hello}} will be replaced with the text that the function returned, in this case, "Hello, world!"

It's generally a good idea to invoke Lua code from the context of a template. This means that from the perspective of a calling page, the syntax is independent of whether the template logic is implemented in Lua or in wikitext. It also avoids the introduction of additional complex syntax into the content namespace of a wiki.

Module structure

The module itself must return a table containing the functions that may be called by {{#invoke:}}. Generally, as shown above, a local variable is declared holding a table, functions are added to this table, and the table is returned at the end of the module code.

Any functions that are not added to this table, whether local or global, will not be accessible by {{#invoke:}}, but globals might be accessible from other modules loaded using require(). It is generally good style for the module to declare all functions and variables local.

Returning text

The module function should usually return a single string; whatever values are returned will be passed through tostring() and then concatenated with no separator. This string is incorporated into the wikitext as the result of the {{#invoke:}}.

At this point in the page parse, templates have already been expanded, parser functions and extension tags have already been processed, and pre-save transforms (e.g. signature tilde expansion and the pipe trick) have already happened. Therefore the module cannot use these features in its output text. For example, if a module returns "Hello, [[world]]! {{welcome}}", the page will read "Hello, world! {{welcome}}".

On the other hand, subst is handled at an earlier stage of processing, so with {{subst:#invoke:}} only other attempted substitutions will not be processed. Since the failed substitution will remain in the wikitext, they will then be processed on the next edit. This should generally be avoided.

Lua language

Tokens

Names (also called identifiers) in Lua can be any string of letters, digits, and underscores, not beginning with a digit. Names are case-sensitive; "foo", "Foo", and "FOO" are all different names.

The following keywords are reserved and may not be used as names:

  • and
  • break
  • do
  • else
  • elseif
  • end
  • false
  • for
  • function
  • if
  • in
  • local
  • nil
  • not
  • or
  • repeat
  • return
  • then
  • true
  • until
  • while

Names starting with an underscore followed by uppercase letters are reserved for internal Lua global variables.

Other tokens are:

  • #
  • %
  • (
  • )
  • *
  • +
  • ,
  • -
  • .
  • ..
  • ...
  • /
  • :
  • ;
  • <
  • <=
  • =
  • ==
  • >
  • >=
  • [
  • ]
  • ^
  • {
  • }
  • ~=

Comments

A comment starts with a -- anywhere outside a string. If the -- is immediately followed by an opening long bracket, the comment continues to the corresponding closing long bracket; otherwise the comment runs to the end of the current line.

-- A comment in Lua starts with a double-hyphen and runs to the end of the line.
--[[ Multi-line strings & comments
     are adorned with double square brackets. ]]
--[=[ Comments like this can have other --[[comments]] nested. ]=]

Data types

Lua is a dynamically-typed language, which means that variables and function arguments have no type, only the values assigned to them. All values carry a type.

Lua has eight basic data types, however only six are relevant to the Scribunto extension. The type() function will return the type of a value.

The tostring() function will convert a value to a string. The tonumber() function will convert a value to a number if possible, and otherwise will return nil. There are no explicit functions to convert a value to other data types.

Numbers are automatically converted to strings when used where a string is expected, e.g. when used with the concatenation operator. Strings recognized by tonumber() are automatically converted to numbers when used with arithmetic operators. When a boolean value is expected, all values other than nil and false are considered to be true.

nil

"Nil" is the data type of nil, which exists to represent the absence of a value. Nil may not be used as a key in a table, and there is no difference between an unassigned table key and a key assigned a nil value.

When converted to a string, the result is "nil". When converted to boolean, nil is considered false.

boolean

Boolean values are true and false.

When converted to a string, the result is "true" or "false". Unlike many other languages, boolean values may not be directly converted to numbers. And unlike many other languages, only false and nil are considered false for boolean conversion; the number 0 and the empty string are both considered true.

string

Lua strings are considered a series of 8-bit bytes; it is up to the application to interpret them in any particular encoding.

String literals may be delimited by either single or double quotes (' or "); like JavaScript and unlike PHP, there is no difference between the two. The following escape sequences are recognized: '\a' (bell), '\b' (backspace), '\f' (form feed), '\n' (newline), '\r' (carriage return), '\t' (horizontal tab), '\v' (vertical tab), '\\' (backslash), '\"' (double quote), and '\'' (single quote). A literal newline may also be included in a string by preceding it with a backslash. Bytes may also be specified using an escape sequence '\ddd', where ddd is the decimal value of the byte in the range 0–255. To include Unicode characters using escape sequences, the individual bytes for the UTF-8 encoding must be specified; in general, it will be more straightforward to enter the Unicode characters directly.

Literal strings can also be defined using long brackets. An opening long bracket consists of an opening square bracket followed by zero or more equal signs followed by another opening square bracket, e.g. [[, [=[, or [=====[. The opening long bracket must be matched by the corresponding closing long bracket, e.g. ]], ]=], or ]=====]. Strings delimited by long brackets do not interpret escape sequences. As a special case, if an opening long bracket is immediately followed by a newline then the newline is not included in the string.

-- This long string
foo = [[
bar\tbaz
]]

-- Is equivalent to this normal string
bar = 'bar\\tbaz\n'

Note that all strings are considered true when converted to boolean. This is unlike most other languages, where the empty string is usually considered false.

number

Lua has only one numeric type, which is typically represented internally as a double-precision floating-point value. In this format, integers between -9007199254740992 and 9007199254740992 may be represented exactly, while higher and lower numbers will suffer from round-off error.

Numbers are specified using a period (.) as a decimal separator and without grouping separators, e.g. 123456.78. Numbers may also be represented using E notation without spaces, e.g. 1.23e-10, 123.45e20, or 1.23E5. Integers may also be specified in hexadecimal notation using a 0x prefix, e.g. 0x3A.

Although NaN and positive and negative infinities are correctly stored and handled, Lua does not provide corresponding literals. The constant math.huge is positive infinity, as is a division such as 1/0, and a division such as 0/0 may be used to quickly generate a NaN.

Note that all numbers are considered true when converted to boolean. This is unlike most other languages, where the number 0 is usually considered false. When converted to a string, finite numbers are represented in decimal, possibly in E notation; NaN is "nan" or "-nan"; and infinities are "inf" or "-inf".

table

Lua tables are associative arrays, much like PHP arrays and JavaScript objects.

Tables are created using curly braces. The empty table is {}. To populate fields on creation, a comma- and/or semicolon-separated list of field specifiers may be included in the braces. These take any of several forms:

  • [expression1] = expression2 uses the (first) value of expression1 as the key and the (first) value of expression2 as the value.
  • 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.

The fields in a table are accessed using bracket notation, e.g. table[key]. String keys that are also valid names may also be accessed using dot notation, e.g. table.key is equivalent to table['key']. Calling a function that is a value in the table may use colon notation, e.g. table:func( ... ), which is equivalent to table['func']( table, ... ).

sequence

An array (also named a sequence or a list) is a table with non-nil values for all positive integers from 1 to N and no value (nil) for all positive integers greater than N. Many Lua functions operate only on arrays, and ignore non-positive-integer keys.

Unlike PHP or JavaScript, however, any value except nil and NaN may be used as a key and no type conversion is performed. These are all valid and distinct:

-- Create table
t = {}

t["foo"] = "foo"
t.bar = "bar"
t[1] = "one"
t[2] = "two"
t[3] = "three"
t[12] = "the number twelve"
t["12"] = "the string twelve"
t[true] = "true"
t[tonumber] = "yes, even functions may be table keys"
t[t] = "yes, a table may be a table key too. Even in itself."

-- This creates a table roughly equivalent to the above
t2 = {
    foo = "foo",
    bar = "bar",
    "one",
    "two",
    [12] = "the number twelve",
    ["12"] = "the string twelve",
    "three",
    [true] = "true",
    [tonumber] = "yes, even functions may be table keys",
}
t2[t2] = "yes, a table may be a table key too. Even in itself."

Similarly, any value except nil may be stored as a value in a table. Storing nil is equivalent to deleting the key from the table, and accessing any key that has not been set will result in a nil value.

Note that tables are never implicitly copied in Lua; if a table is passed as an argument to the function and the function manipulates the keys or values in the table, those changes will be visible in the caller.

When converted to a string, the usual result is "table" but may be overridden using the __tostring metamethod. Even the empty table is considered true as a boolean.

function

Functions in Lua are first-class values: they may be created anonymously, passed as arguments, assigned to variables, and so on.

Functions are created using the function keyword, and called using parentheses. Syntactic sugar is available for named functions, local functions, and functions that act like member functions to a table. See Function declarations and Function calls below for details.

Lua functions are closures, meaning that they maintain a reference to the scope in which they are declared and can access and manipulate variables in that scope.

Like tables, if a function is assigned to a different variable or passed as an argument to another function, it is still the same underlying "function object" that will be called.

When converted to a string, the result is "function".

Unsupported types

The userdata type is used to hold opaque values for extensions to Lua written in other languages; for example, a userdata might be used to hold a C pointer or struct. To allow for use of Scribunto in hosting environments where custom-compiled code is not allowed, no such extensions are used.

The thread type represents the handles for coroutines, which are not available in Scribunto's sandbox.

Metatables

Every table may have an associated table known as a metatable. The fields in the metatable are used by some operators and functions to specify different or fallback behavior for the table. The metatable for a table may be accessed using the getmetatable() function, and set with the setmetatable() function.

When being accessed for their meta functions, metatable fields are accessed as if with rawget().

Metatable fields that affect the table itself are:

__index
This is used when a table access t[key] would return nil. If the value of this field is a table, the access will be repeated in that table, i.e. __index[key] (which may invoke that table's metatable's __index). If the value of this field is a function, the function will be called as __index( t, key ). The rawget() function bypasses this metamethod.
__newindex
This is used when assigning a key to a table t[key] = value where rawget( t, key ) would return nil. If the value of this field is a table, the assignment will be repeated in that table, i.e. __newindex[key] = value (which may invoke that table's metatable's __newindex). If the value of this field is a function, the function will be called as __newindex( t, key, value ). The rawset() function bypasses this metamethod.
__call
This is used when function call syntax is used on a table, t( ··· ). The value must be a function, which is called as something like __call( t, ··· ).
__mode
This is used to make tables holding weak references. The value must be a string. By default, any value that is used as a key or as a value in a table will not be garbage collected. But if this metafield contains the letter 'k', keys may be garbage collected if there are no non-weak references, and if it contains 'v' values may be; in either case, both the corresponding key and value are removed from the table. Note that behavior is undefined if this field is altered after the table is used as a metatable.

Other metatable fields include:

For binary operators, Lua looks first at the left argument's metatable (if any) then the right's when looking for a metamethod to use.
For relational operators, the metamethod is only used if the same function is specified in both arguments' metatables. Different anonymous functions, even with identical body and closure, may not be considered the same.
* __metatable affects both getmetatable() and setmetatable()

Note: In Lua, all strings also share a single metatable, in which __index refers to the string table. This metatable is not accessible in Scribunto, nor is the referenced string table; the string table available to modules is a copy.

Variables

Variables are places that store values. There are three kinds of variables in Lua: global variables, local variables, and table fields.

A name represents a global or local variable (or a function argument, which is just a kind of local variable). Variables are assumed to be global unless explicitly declared as local using the local keyword. Any variable that has not been assigned a value is considered to have a nil value.

Global variables are stored in a standard Lua table called an environment; this table is often available as the global variable _G. It is possible to set a metatable for this global variable table; the __index and __newindex metamethods will be called for accesses of and assignments to global variables just as they would for accesses of and assignments to fields in any other table.

The environment for a function may be accessed using the getfenv() function and changed using the setfenv() function; in Scribunto, these functions are severely restricted if they are available at all.

Local variables are lexically scoped; see Local variable declarations for details.

Expressions

An expression is something that has values: literals (numbers, strings, true, false, nil), anonymous function declarations, table constructors, variable references, function calls, the vararg expression, expressions wrapped in parentheses, unary operators applied to expressions, and expressions combined with binary operators.

Most expressions have one value; function calls and the vararg expression can have any number. Note that wrapping a function call or vararg expression in parentheses will lose all except the first value.

Expression lists are comma-separated lists of expressions. All except the last expression are forced to one value (dropping additional values, or using nil if the expression has no values); all values from the last expression are included in the values of the expression list.

Arithmetic operators

Lua supports the usual arithmetic operators: addition, subtraction, multiplication, division, modulo, exponentiation, and negation.

When all operands are numbers or strings for which tonumber() returns non-nil, the operations have their usual meaning.

If either operand is a table with an appropriate metamethod, the metamethod will be called.

Operator Function Example Metamethod Notes
+ Addition a + b __add
- Subtraction a - b __sub
* Multiplication a * b __mul
/ Division a / b __div division by zero is not an error; NaN or infinity will be returned
% Modulo a % b __mod defined as a % b == a - math.floor( a / b ) * b
^ Exponentiation a ^ b __pow non-integer exponents are allowed
- Negation -a __unm

Relational operators

The relational operators in Lua are ==, ~=, <, >, <=, and >=. The result of a relational operator is always a boolean.

Equality (==) first compares the types of its operands; if they are different, the result is false. Then it compares the values: nil, boolean, number, and string are compared in the expected manner. Functions are equal if they refer to the exact same function object; function() end == function() end will return false, as it is comparing two different anonymous functions. Tables are by default compared in the same manner, but this may be changed using the __eq metamethod.

Inequality (~=) is the exact negation of equality.

For the ordering operators, if both are numbers or both are strings, they are compared directly. Next, metamethods are checked:

  • a < b uses __lt
  • a <= b uses __le if available, or if __lt is available then it is considered equivalent to not ( b < a )
  • a > b is considered equivalent to b < a
  • a >= b is considered equivalent to b <= a

If the necessary metamethods are not available, an error is raised.

Logical operators

The logical operators are and, or, and not. All use the standard interpretation where nil and false are considered false and anything else is considered true.

For and, if the left operand is considered false then it is returned and the second operand is not evaluated; otherwise the second operand is returned.

For or, if the left operand is considered true then it is returned and the second operand is not evaluated; otherwise the second operand is returned.

For not, the result is always true or false.

Note that and and or short circuit. For example, foo() or bar() will only call bar() if foo() returns false or nil as its first value.

Concatenation operator

The concatenation operator is two dots, used as a .. b. If both operands are numbers or strings, they are converted to strings and concatenated. Otherwise if a __concat metamethod is available, it is used. Otherwise, an error is raised.

Note that Lua strings are immutable and Lua does not provide any sort of "string builder", so a loop that repeatedly does a = a .. b will have to create a new string for each iteration and eventually garbage-collect the old strings. If many strings need concatenating, it may be faster to use string.format() or to insert all the strings into a sequence and use table.concat() at the end.

Length operator

The length operator is #, used as #a. If a is a string, it returns the length in bytes. If a is a sequence table, it returns the length of the sequence.

If a is a table that is not a sequence, the #a may return any value N such that a[N] is not nil and a[N+1] is nil, even if there are non-nil values at higher indexes. For example,

-- This is not a sequence, because a[3] is nil and a[4] is not
a = { 1, 2, nil, 4 }

-- This may output either 2 or 4.
-- And this may change even if the table is not modified.
mw.log( #a )

Operator precedence

Lua's operator precedence, from highest to lowest:

  • ^
  • not # - (negation)
  • * / %
  • + - (subtraction)
  • ..
  • < > <= >= ~= ==
  • and
  • or

Within a precedence level, most binary operators are left-associative, i.e. a + b + c is interpreted as (a + b) + c. Exponentiation and concatenation are right-associative, i.e. a ^ b ^ c is interpreted as a ^ (b ^ c).

Function calls

Lua function calls look like those in most other languages: a name followed by a list of arguments in parentheses:

func( exp-list )

As is usual with expression lists in Lua, the last expression in the list may supply multiple argument values.

If the function is called with fewer values in the expression list than there are arguments in the function definition, the extra arguments will have a nil value. If the expression list contains more values than there are arguments, the excess values are discarded. It is also possible for a function to take a variable number of arguments; see Function declarations for details.

Lua also allows direct calling of a function return value, i.e. func()(). If an expression more complex than a variable access is needed to determine the function to be called, a parenthesized expression may be used in place of the variable access.

Lua has syntactic sugar for two common cases. The first is when a table is being used as an object, and the function is to be called as a method on the object. The syntax

table:name( exp-list )

is exactly equivalent to

table.name( table, exp-list )

The second common case is Lua's method of implementing named arguments by passing a table containing the name-to-value mappings as the only positional argument to the function. In this case, the parentheses around the argument list may be omitted. This also works if the function is to be passed a single literal string. For example, the calls

func{ arg1 = exp, arg2 = exp }
func"string"

are equivalent to

func( { arg1 = exp, arg2 = exp } )
func( "string" )

These may be combined; the following calls are equivalent:

table:name{ arg1 = exp, arg2 = exp }
table.name( table, { arg1 = exp, arg2 = exp } )

Function declarations

The syntax for function declaration looks like this:

function ( var-list )
    block
end

All variables in var-list are local to the function, with values assigned from the expression list in the function call. Additional local variables may be declared inside the block.

When the function is called, the statements in block are executed after local variables corresponding to var-list are created and assigned values. If a return statement is reached, the block is exited and the values of the function call expression are those given by the return statement. If execution reaches the end of the function's block without encountering a return statement, the result of the function call expression has zero values.

Lua functions are lexical closures. A common idiom is to declare "private static" variables as locals in the scope where the function is declared. For example,

-- This returns a function that adds a number to its argument
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 ) )
-- prints 11

A function may be declared to accept a variable number of arguments, by specifying ... as the final item in the var-list:

function ( var-list, ... )
    block
end


local join = function ( separator, ... )
    -- get the extra arguments as a 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' )
-- returns the string "foo, bar, baz"

The select() function is designed to work with the varargs expression; in particular, select( '#', ... ) should be used instead of #{ ... } to count the number of values in the varargs expression.

Lua provides syntactic sugar to combine function declaration and assignment to a variable; see Function declaration statements for details.

Note that this will not work:

local factorial = function ( n )
    if n <= 2 then
        return n
    else
        return n * factorial( n - 1 )
    end
end

Since the function declaration is processed before the local variable assignment statement is complete, "factorial" inside the function body refers to the (probably undefined) global variable of that name. This problem may be avoided by declaring the local variable first and then assigning it in a subsequent statement, or by using the function declaration statement syntax.

Statements

A statement is the basic unit of execution: one assignment, control structure, function call, variable declaration, etc.

A chunk is a sequence of statements, optionally separated by semicolons. A chunk is basically considered the body of an anonymous function, so it can declare local variables, receive arguments, and return values.

A block is also a sequence of statements, just like a chunk. A block can be delimited to create a single statement: do block end. These may be used to limit the scope of local variables, or to add a return or break in the middle of another block.

Assignments

variable-list = expression-list

The variable-list is a comma-separated list of variables; the expression-list is a comma-separated list of one or more expressions. All expressions are evaluated before any assignments are performed, so a, b = b, a will swap the values of a and b.

Local variable declarations

local variable-list

local variable-list = expression-list

Local variables may be declared anywhere within a block. The first form, without an expression list, declares the variables but does not assign a value so all variables have nil as a value. The second form assigns values to the local variables, as described in Assignments above.

Note that visibility of the local variable begins with the statement after the local variable declaration. So a declaration like local x = x declares a local variable x and assigns it the value of x from the outer scope. The local variable remains in scope until the end of the innermost block containing the local variable declaration.

Control structures

while exp do block end

The while statement repeats a block as long as an expression evaluates to a true value.

repeat block until exp

The repeat statement repeats a block until an expression evaluates to a true value. Local variables declared inside the block may be accessed in the expression.

for name = exp1, exp2, exp3 do block end
for name = exp1, exp2 do block end

This first form of the for loop will declare a local variable, and repeat the block for values from exp1 to exp2 adding exp3 on each iteration. Note that exp3 may be omitted entirely, in which case 1 is used, but non-numeric values such as nil and false are an error. All expressions are evaluated once before the loop is started.

This form of the for loop is roughly equivalent to

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

except that the variables var, limit, and step are not accessible anywhere else. Note that the variable name is local to the block; to use the value after the loop, it must be copied to a variable declared outside the loop.

for var-list in exp-list do block end

The second form of the for loop works with iterator functions. As in the first form, the exp-list is evaluated only once before beginning the loop.

This form of the for loop is roughly equivalent to

do
    local func, static, var = exp-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

except that again the variables func, static, and var are not accessible anywhere else. Note that the variables in var-list are local to the block; to use them after the loop, they must be copied to variables declared outside the loop.

Often the exp-list is a single function call that returns the three values. If the iterator function can be written so it only depends on the parameters passed into it, that would be the most efficient. If not, Programming in Lua suggests that a closure be preferred to returning a table as the static variable and updating its members on each iteration.

if exp1 then block1 elseif exp2 then block2 else block3 end

Executes block1 if exp1 returns true, otherwise executes block2 if exp2 returns true, and block3 otherwise. The else block3 portion may be omitted, and the elseif exp2 then block2 portion may be repeated or omitted as necessary.

return expression-list

The return statement is used to return values from a function or a chunk (which is just a function). The expression-list is a comma-separated list of zero or more expressions.

Lua implements tail calls: if expression-list consists of exactly one expression which is a function call, the current stack frame will be reused for the call to that function. This has implication for functions that deal with the call stack, such as getfenv() and debug.traceback().

The return statement must be the last statement in its block. If for some reason a return is needed in the middle of a block, an explicit block do return end may be used.

break

The break statement is used to terminate the execution of a while, repeat, or for loop, skipping to the next statement after the loop.

The break statement must be the last statement in its block. If for some reason a break is needed in the middle of a block, an explicit block do break end may be used.

Function calls as statements

A function call may be used as a statement; in this case, the function is being called only for any side effects it may have (e.g. mw.log() logs values) and any return values are discarded.

Function declaration statements

Lua provides syntactic sugar to make declaring a function and assigning it to a variable more natural. The following pairs of declarations are equivalent

-- Basic declaration
function func( var-list ) block end
func = function ( var-list ) block end
-- Local function
local function func( var-list ) block end
local func; func = function ( var-list ) block end
-- Function as a field in a table
function table.func( var-list ) block end
table.func = function ( var-list ) block end
-- Function as a method in a table
function table:func( var-list ) block end
table.func = function ( self, var-list ) block end

Note the colon notation here parallels the colon notation for function calls, adding an implicit argument named "self" at the beginning of the arguments list.

Error handling

Errors may be "thrown" using the error() and assert() functions. To "catch" errors, use pcall() or xpcall(). Note that certain internal Scribunto errors cannot be caught in Lua code.

Garbage collection

Lua performs automatic memory management. This means that you have to worry neither about allocating memory for new objects nor about freeing it when the objects are no longer needed. Lua manages memory automatically by running a garbage collector from time to time to collect all dead objects (that is, objects that are no longer accessible from Lua) and objects that are only reachable via weak references. All memory used by Lua is subject to automatic management: tables, functions, strings, etc.

Garbage collection happens automatically, and cannot be configured from within Scribunto.

Standard libraries

The standard Lua libraries provide essential services and performance-critical functions to Lua. Only those portions of the standard libraries that are available in Scribunto are documented in this manual. See main standard libraries reference page for a description of the libraries and their methods.

Scribunto libraries

All Scribunto libraries are located in the table mw. See main Scribunto libraries reference page for a description of the libraries and their methods.

Differences from standard Lua

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()
Only works on tables as 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.


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:
os.clock()
os.date()
os.difftime()
os.time()
debug.*
Most of the functions are insecure. Available functions are:
debug.traceback()


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.
Text above can be found here (edit)
Advertisement