13 - Metatables and Metamethods

Usually, tables in Lua have a quite predictable set of operations. We can add key-value pairs, we can check the value associated with a key, we can traverse all key-value pairs, and that is all. We cannot add tables, we cannot compare tables, and we cannot call a table.

Metatables allow us to change the behavior of a table. For instance, using metatables, we can define how Lua computes the expression a+b, where a and b are tables. Whenever Lua tries to add two tables, it checks whether either of them has a metatable and whether that metatable has an __add field. If Lua finds this field, it calls the corresponding value (the so-called metamethod, which should be a function) to compute the sum.

Each table in Lua may have its own metatable. (As we will see later, userdata also can have metatables.) Lua always create new tables without metatables:

    t = {}
    print(getmetatable(t))   --> nil
We can use setmetatable to set or change the metatable of any table:
    t1 = {}
    setmetatable(t, t1)
    assert(getmetatable(t) == t1)
Any table can be the metatable of any other table; a group of related tables may share a common metatable (which describes their common behavior); a table can be its own metatable (so that it describes its own individual behavior). Any configuration is valid.