Skip to content
Pedro Andrade edited this page Mar 20, 2017 · 23 revisions

Useful Lua Functions

The descriptions described in this document were extracted from Programming in Lua.

  • debug.getinfo: The main introspective function in the debug library is the debug.getinfo function. Its first parameter may be a function or a stack level. When you call debug.getinfo(foo) for some function foo, you get a table with some data about that function. The table may have the following fields:

    • source: Where the function was defined. If the function was defined in a string (through loadstring), source is that string. If the function was defined in a file, source is the file name prefixed with a @.
    • short_src: A short version of source (up to 60 characters), useful for error messages.
    • linedefined: The line of the source where the function was defined.
    • what: What this function is. Options are "Lua" if foo is a regular Lua function, "C" if it is a C function, or "main" if it is the main part of a Lua chunk.
    • name: A reasonable name for the function.
    • namewhat: What the previous field means. This field may be "global", "local", "method", "field", or "" (the empty string). The empty string means that Lua did not find a name for the function.
    • nups: Number of upvalues of that function.
    • func: The function itself that is active at that level.

    When foo is a C function, Lua does not have much data about it. For such functions, only the fields what, name, and namewhat are relevant. When you call debug.getinfo(n) for some number n, you get data about the function active at that stack level. For instance, if n is 1, you get data about the function doing the call. (When n is 0, you get data about getinfo itself, a C function). If n is larger than the number of active functions in the stack, debug.getinfo returns nil. When you query an active function, calling debug.getinfo with a number, the result table has an extra field, currentline, with the line where the function is at that moment.

  • debug.sethook: The hook mechanism of the debug library allows us to register a function that will be called at specific events as your program runs. There are four kinds of events that can trigger a hook:

    1. call events happen every time Lua calls a function;
    2. return events happen every time a function returns;
    3. line events happen when Lua starts executing a new line of code; and
    4. count events happen after a given number of instructions. Lua calls hooks with a single argument, a string describing the event that generated the call: "call", "return", "line", or "count". Moreover, for line events, it also passes a second argument, the new line number. We can always use debug.getinfo to get more information inside a hook.

    To register a hook, we call debug.sethook with two or three arguments:

    1. a user-defined hook function, that gets the event activated (first argument) and the line number (second argument);
    2. a string that describes the events we want to monitor; and
    3. an optional argument is a number that describes at what frequency we want to get count events. To monitor the call, return, and line events, we add their first letters (c, r, or l) in the mask string. To monitor the count event, we simply supply a counter as the third argument. To turn off hooks, we call debug.sethook with no arguments.
  • dofile: Loads a given file, adding all the global objects to _G. It works as an auxiliary function for loadfile, as in the example below:

     function dofile(filename)
       local f = assert(loadfile(filename))
       return f()
     end
  • loadlib: provides all the functionality of dynamic linking in a single function. Its has two string arguments: the complete path of the library and the name of an initialization function. So, a typical call to it looks like:

     local path = "/usr/local/lua/lib/libluasocket.so"
     local f = loadlib(path, "luaopen_socket")

    loadlib() loads the given library and links Lua to it. However, it does not open the library (that is, it does not call the initialization function); instead, it returns the initialization function as a Lua function, so that we can call it directly from Lua. If there is any error loading the library or finding the initialization function, loadlib returns nil plus an error message. We can improve our previous fragment so that it checks for errors and calls the initialization function:

    local path = "/usr/local/lua/lib/libluasocket.so"
    -- or path = "C:\\windows\\luasocket.dll"
    local f = assert(loadlib(path, "luaopen_socket"))
    f()  -- actually open the library

    Typically, we could expect a library distribution to include a stub file similar to that previous code fragment. Then, to install the library, we put the actual binary shared library anywhere, edit the stub to reflect the real path, and then add the stub file in a directory in our LUA_PATH. With this setting, we can use require() to open the C library.

  • loadfile: loads a Lua chunk from a file, compiles it and returns the compiled chunk as a function. If there is any error while loading the file, it returns nil plus the error instead.

  • loadstring: similar to loadfile, except that it reads its chunk from a string, not from a file.

    f = loadstring("i = i + 1")
    i = 0
    f(); print(i)   --> 1
    f(); print(i)   --> 2
  • rawget(t, k): gets the value in key k of table t without invoking any metamethod.

  • rawset(t, k, v): sets the value v in key k of table t without invoking any metamethod.

  • setfenv: Useful to work with non-global environments.

  • setmetatable: Metatables are ordinary Lua tables that define the behavior of a value under certain special operations. The keys in a metatable are derived from event names; the corresponding values are called metamethods. Metatables control the operations listed next. Each operation is identified by its corresponding name.

    • __call: When a table executed as a function, such as myTable('foo') and the metatable has a function __call, such function is invoked (passing the table as the first argument, followed by any specified arguments) and the return value is returned.

    • __index: A mechanism for inheritance-like methods. When accessing myTable[key] and key does not belong to the table, __index is activated. If __index is a function, it is called with the table and the key as arguments; the return value of such function is returned as the result. If __index is another table, the value of the key in that table is returned (and if it doesn't exist in that table, but that table's metatable has an __index, then it continues on up). rawget can be used to skip this metamethod.

    • __mode: Control weak references. A string value with one or both of the characters 'k' and 'v' which specifies that the the keys and/or values in the table are weak references.

    • __newindex: Metamethod called when one tries to assign to a key that does not exist in a table. If the key exists, the metamethod is not triggered. If __newindex does not set the key on the table (using rawset) then the value is not added to the table.

      local t = {}
      
      local m = setmetatable({}, {__newindex = function(table, key, value)
      t[key] = value
      end})
      
      m[123] = 456
      print(m[123]) --> nil
      print(t[123]) --> 456
    • __metatable: protects metatables. If one do not want a program to change the contents of a metatable, you set its __metatable field. With that, the program cannot access the metatable (and therefore cannot change it).

    • __tostring: When formatting an object, tostring() first checks whether the object has a metatable with a __tostring field. If this is the case, tostring() calls the corresponding value (which must be a function) to do its job, passing the object as argument. Whatever this metamethod returns is the result of tostring(). Note that print() always calls tostring() to format its output.

    • __gc: This metamethod only works for userdata values. When a userdatum is about to be collected and its metatable has a __gc field, Lua calls the value of this field (which should be a function), passing as an argument the userdatum itself. This function can then release any resource associated with that userdatum.

    • __len: a function to define length operator #. It gets the object itself as argument.

    • __unm: Unary minus. When writing -myTable, if the metatable has a __unm key pointing to a function, that function is invoked (passing the table), and the return value used as the value of -myTable.

    • __add: Addition. When writing myTable + object or object + myTable, if myTable's metatable has an __add key pointing to a function, that function is invoked (passing the left and right operators in order) and the return value used. If both operands are tables, the left table is checked before the right table for the presence of an __add metaevent.

    • __sub: Subtraction. Similar to addition, using the - operator.

    • __mul: Multiplication. Similar to addition, using the * operator.

    • __div: Division. Similar to addition, using the / operator.

    • __mod: Modulo. Similar to addition, using the % operator.

    • __pow: Involution. Similar to addition, using the ^ operator.

    • __concat: Concatenation. Similar to addition, using the .. operator.

    • __eq: Check for equality. This method is invoked when myTable1 == myTable2 is evaluated, but only if both tables have the exact same metamethod for __eq. For example, see the following code:

       t1a = {}
       t1b = {}
       t2  = {}
       mt1 = {__eq = function(o1, o2) return 'whee' end}
       mt2 = {__eq = function(o1, o2) return 'whee' end}
      
       setmetatable(t1a, mt1)
       setmetatable(t1b, mt1)
       setmetatable(t2,  mt2)
      
       print(t1a == t1b) --> true
       print(t1a == t2)  --> false

      If the function returns nil or false, the result of the comparison is false; otherwise, the result is true. If t1 and t2 are referencing the same table, __eq is not invoked for t1 == t2 (the result will automatically be true).

    • __lt: Check for less-than. Similar to equality, using <. Greater-than is evaluated by reversing the order of the operands passed to the __lt function.

    • __le: Check for less-than-or-equal. Similar to equality, using <=. Greater-than-or-equal is evaluated by reversing the order of the operands passed to __le.

  • getmetatable: Return the metatable of a given object.

  • unpack: Split a table into multiple arguments.

    function multiple_args(...)
      local arguments = {...}  -- pack the arguments in a table
      -- do something --
      return unpack(arguments) -- multiple arguments from a table
    end
  • setfenv: Change the environment of a function. It receives the function and the new environment. Instead of the function itself, you can also give a number, meaning the active function at that given stack level. Number 1 means the current function, number 2 means the function calling the current function, and so on. You can populate your new environment using inheritance also:

    a = 1
    local newgt = {}        -- create new environment
    setmetatable(newgt, {__index = _G})
    setfenv(1, newgt)       -- set it
    print(a)                --> 1

    In this code, the new environment inherits both print and a from the old one. Nevertheless, any assignment goes to the new table.

  • require: A higher-level function to load and run libraries. Roughly, it does the same job as dofile, but with two important differences. First, require searches for the file in a path; second, require controls whether a file has already been run to avoid duplicating the work. Because of these features, require is the preferred function in Lua for loading libraries. For instance, if the path is

    ?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua
    

    then the call require"lili" will try to open the following files:

    lili
    lili.lua
    c:\windows\lili
    /usr/local/lua/lili/lili.lua
    

    The only things that require fixes is the semicolon (as the component separator) and the interrogation mark; everything else (such as directory separators or file extensions) is defined in the path. To determine its path, require first checks the global variable LUA_PATH. If the value of LUA_PATH is a string, that string is the path. Otherwise, require checks the environment variable LUA_PATH. Finally, if both checks fail, require uses a fixed path (typically "?;?.lua", although it is easy to change that when you compile Lua).

String patterns

A character class is used to represent a set of characters. The following combinations are allowed in describing a character class:

  • x: (where x is not one of the magic characters ^$()%.[]*+-?) represents the character x itself.
  • .: (a dot) represents all characters.
  • %a: represents all letters.
  • %c: represents all control characters.
  • %d: represents all digits.
  • %g: represents all printable characters except space.
  • %l: represents all lowercase letters.
  • %p: represents all punctuation characters.
  • %s: represents all space characters.
  • %u: represents all uppercase letters.
  • %w: represents all alphanumeric characters.
  • %x: represents all hexadecimal digits.
  • %x: (where x is any non-alphanumeric character) represents the character x. This is the standard way to escape the magic characters. Any punctuation character (even the non magic) can be preceded by a % when used to represent itself in a pattern.
  • [set]: represents the class which is the union of all characters in set. A range of characters can be specified by separating the end characters of the range, in ascending order, with a -. All classes %x described above can also be used as components in set. All other characters in set represent themselves. For example, [%w_] (or [_%w]) represents all alphanumeric characters plus the underscore, [0-7] represents the octal digits, and [0-7%l%-] represents the octal digits plus the lowercase letters plus the - character. The interaction between ranges and classes is not defined. Therefore, patterns like[%a-z] or [a-%%] have no meaning.
  • [^set]: represents the complement of set, where set is interpreted as above.

For all classes represented by single letters (%a, %c, etc.), the corresponding uppercase letter represents the complement of the class. For instance, %S represents all non-space characters.

The definitions of letter, space, and other character groups depend on the current locale. In particular, the class [a-z] may not be equivalent to %l.

A pattern item can be

  • a single character class, which matches any single character in the class;
  • a single character class followed by '*', which matches 0 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;
  • a single character class followed by '+', which matches 1 or more repetitions of characters in the class. These repetition items will always match the longest possible sequence;
  • a single character class followed by '-', which also matches 0 or more repetitions of characters in the class. Unlike '*', these repetition items will always match the shortest possible sequence;
  • a single character class followed by '?', which matches 0 or 1 occurrence of a character in the class;
  • %n, for n between 1 and 9; such item matches a substring equal to the n-th captured string;
  • %bxy, where x and y are two distinct characters; such item matches strings that start with x, end with y, and where the x and y are balanced. This means that, if one reads the string from left to right, counting +1 for an x and -1 for a y, the ending y is the first y where the count reaches 0. For instance, the item %b() matches expressions with balanced parentheses.
  • %f[set], a frontier pattern; such item matches an empty string at any position such that the next character belongs to set and the previous character does not belong to set. The set set is interpreted as previously described. The beginning and the end of the subject are handled as if they were the character '\0'.

A pattern is a sequence of pattern items. A caret '^' at the beginning of a pattern anchors the match at the beginning of the subject string. 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.

A pattern can contain sub-patterns enclosed in parentheses; they describe captures. When a match succeeds, the substrings of the subject string that match captures are stored (captured) for future use. Captures are numbered according to their left parentheses. For instance, in the pattern "(a*(.)%w(%s*))", the part of the string matching "a*(.)%w(%s*)" is stored as the first capture (and therefore has number 1); the character matching "." is captured with number 2, and the part matching "%s*" has number 3.

As a special case, the empty capture () captures the current string position (a number). For instance, if we apply the pattern "()aa()" on the string "flaaap", there will be two captures: 3 and 5.

Even with character classes this is still very limiting, because we can only match strings with a fixed length. To solve this, patterns support these four repetition operators:

  • *: Match the previous character (or class) zero or more times, as many times as possible.
  • +: Match the previous character (or class) one or more times, as many times as possible.
  • -: Match the previous character (or class) zero or more times, as few times as possible.
  • ?: Make the previous character (or class) optional.

There are some functions that use patterns in Lua:

  • string.match (s, pattern [, init]): Looks for the first match of pattern in the string s. If it finds one, then match returns the captures from the pattern; otherwise it returns nil. If pattern specifies no captures, then the whole match is returned. A third, optional numerical argument init specifies where to start the search; its default value is 1 and can be negative.

  • string.gmatch (s, pattern): Returns an iterator function that, each time it is called, returns the next captures from pattern over the string s. If pattern specifies no captures, then the whole match is produced in each call. As an example, the following loop will iterate over all the words from string s, printing one per line:

     s = "hello world from Lua"
     for w in string.gmatch(s, "%a+") do
       print(w)
     end

    The next example collects all pairs key=value from the given string into a table:

     t = {}
     s = "from=world, to=Lua"
     for k, v in string.gmatch(s, "(%w+)=(%w+)") do
       t[k] = v
     end

    For this function, a caret '^' at the start of a pattern does not work as an anchor, as this would prevent the iteration.

  • string.gsub (s, pattern, repl [, n]): Returns a copy of s in which all (or the first n, if given) occurrences of the pattern have been replaced by a replacement string specified by repl, which can be a string, a table, or a function. string.gsub also returns, as its second value, the total number of matches that occurred. The name gsub comes from Global SUBstitution. If repl is a string, then its value is used for replacement. If repl is a table, then the table is queried for every match, using the first capture as the key. If repl is a function, then this function is called every time a match occurs, with all captured substrings passed as arguments, in order. In any case, if the pattern specifies no captures, then it behaves as if the whole pattern was inside a capture. If the value returned by the table query or by the function call is a string or a number, then it is used as the replacement string; otherwise, if it is false or nil, then there is no replacement (that is, the original match is kept in the string).

    Here are some examples:

     x = string.gsub("hello world", "(%w+)", "%1 %1")
     --> x="hello hello world world"
     
     x = string.gsub("hello world", "%w+", "%0 %0", 1)
     --> x="hello hello world"
     
     x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
     --> x="world hello Lua from"
     
     x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
     --> x="home = /home/roberto, user = roberto"
     
     x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
           return load(s)()
         end)
     --> x="4+5 = 9"
     
     local t = {name="lua", version="5.2"}
     x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
     --> x="lua-5.2.tar.gz"
Clone this wiki locally