This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.
Programming in Lua | ||
Part II. Tables and Objects Chapter 13. Metatables and Metamethods |
It is a common practice for some libraries to define their own fields in metatables. So far, all the metamethods we have seen are for the Lua core. It is the virtual machine that detects that the values involved in an operation have metatables and that these metatables define metamethods for that operation. However, because the metatable is a regular table, anyone can use it.
The tostring
function provides a typical example.
As we saw earlier, tostring
represents tables in a
rather simple format:
print({}) --> table: 0x8062ac0(Note that
print
always calls tostring
to format its output.)
However, 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 an argument.
Whatever this metamethod returns is the result of tostring
.
In our example with sets,
we have already defined a function to present a set as a string.
So, we need only to set the __tostring
field in the set metatable:
Set.mt.__tostring = Set.tostringAfter that, whenever we call
print
with a set as its argument,
print
calls tostring
that calls Set.tostring
:
s1 = Set.new{10, 4, 5} print(s1) --> {4, 5, 10}
The setmetatable
/getmetatable
functions use a metafield also,
in this case to protect metatables.
Suppose you want to protect your sets,
so that users can neither see nor change their metatables.
If you set a __metatable
field in the metatable,
getmetatable
will return the value of this field,
whereas setmetatable
will raise an error:
Set.mt.__metatable = "not your business" s1 = Set.new{} print(getmetatable(s1)) --> not your business setmetatable(s1, {}) stdin:1: cannot change protected metatable
Copyright © 2003–2004 Roberto Ierusalimschy. All rights reserved. |