Lua Virtualization

lua-users home
wiki

In the Lua language, values are only partly "virtualizable". Here, virtualizable means that any object with a metatable (table or userdata) can act as if it were a value of any other type, including the built-in types.

Following is a summary of how close Lua (5.1) is to being virtualizable:

   Operation           Example             Works?     Metamethods/comments
   ---------           -------             ------     --------------------
Numbers
   Arithmetic          a + b               Yes        __add, __sub, __mul, __div, __pow, __unm
   Equality            a == b              Limited[*] __eq
   Ordering            a < b               Limited[*] __lt, __le

Booleans
   Truth value         if a then           No         Would add overhead to the idiom 'if table[key] then'
   Boolean Logic       not a, a and b      No

Strings
   Concatenation       a .. b              Yes        __concat  (see below)
   Get length          string.len(a)       No[!]
   Other utility       string.find, etc.   No[!]

Tables
   Indexing            a[b]                Yes        __index
   Write to index      a[b] = c            Yes        __newindex
   Length              #a                  Mostly     __len (but requires userdata before 5.2)
   Iterating           for x in pairs(a)   No         Fix is trivial [#]
   raw operations      rawget(a,k)         No
   array functions     table.insert(a,b)   No

Functions
   Invoking            a(x, y)             Yes        __call [+]
   
Threads
   Resuming            coroutine.resume(a) No[!]

File handles           io.type(a), ...     No[!]      See also I/O library abstraction [@]

Misc
   String repr.        tostring(a)         Limited    __tostring (not honored by C lua_tostring)
   type function       type(a)             No

[*] Lua defines an equality or inequality among different types to always yield false. The __eq metamethod also always returns true for values that are raw equal, but this doesn't support the behavior of the value NaN=0/0, where typically NaN ~= NaN.

[+] There are a couple of places in Lua where the __call metamethod is not checked. One of these is the __index metamethod itself (this affects FuncTables).

[!] Native types can have metatables, allowing you to using : notation (eg. aString:find(aPattern)), which is virtualizable. Only some types like strings have the metatable defined by default, but it can be added via debug.setmetatable.

[#] See GeneralizedPairsAndIpairs for virtualizing pairs/ipairs/next. Also see LuaFiveTwo.

[@] LuaList:2008-07/msg00345.html, LuaList:2005-05/msg00178.html

Advantages of virtualization:

Disadvantages:

RiciLake adds:

Note: In the case of a .. b where one of a and b is a number and the other one is an object with a __concat metamethod, the number will be converted to a string before the metamethod is called. Also, .. is right-associative, but a has priority if both a and b have __concat metamethods. So presented with a .. b .. c, where all three have metamethods, the sequence will be: ameta.__concat(a, bmeta.__concat(b, c)). Furthermore, in the case of a .. 34 .. 56 the result will be ameta.__concat(a, "3456"). Some of these might be surprising.

RecentChanges · preferences
edit · history
Last edited September 25, 2010 3:10 am GMT (diff)