Lua Virtualization |
|
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 the latest release of Lua (5.0.2) is to supporting this:
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'
Negation not a 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
Iterating for x in pairs(a) No
for x in ipairs(a) No Fix is trivial with small overhead
Functions
Invoking a(x, y) Yes __call +
Threads
Resuming coroutine.resume(a) No
Misc
String repr. tostring(a) Limited __tostring (not honored by C lua_tostring)
* Limited: Lua defines an equality or inequality among different types to always yield false.
+ 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).
Advantages of virtualization:
Disadvantages:
RiciLake adds:
I made a couple of changes to the chart, I hope whoever created this page doesn't mind. Also, I put code at GeneralizedPairsAndIpairs which "virtualizes" (if you like) pairs and ipairs; it relies on some 5.1 API calls but could be easily modified for 5.0.2.
Some (but not all) of the holes are filled-in in Lua 5.1. In particular, each native type has a metatable, allowing you to write string functions in : notation (eg. aString:find(aPattern)), which I think deals with all of the package.method issues in the chart. (The math library is not introduced into the Number metatable as of 5.1work6, but it is trivial to do.)
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.