Lua metatable examples

Lua has exactly one data structure — tables. And it uses those to implement everything else.

This is how inheritance works in lua:

t1 = {a = 3} -- t1 is a table with one name-value pair.
t2 = {} -- t2 is an empty table.
setmetatable(t1, t2) -- t2 is t1's metatable.
t3 = {c = 5} -- t3 is just another table like t1.

t2.__index = t3 -- when a lookup fails in t1, t2 will look for a value
-- in t3.

print(t1.a)
print(t1.b)
print(t1.c)

And the output is here:
$ lua lua_fun.lua
3
nil
5

This page explains with more detail.

When I first read this stuff, I wondered why I I couldn’t just make the metatable t2 be the place where t1 goes when a lookup fails, rather than require t3 to hold the defaults. Then I realized that __index doesn’t necessarilly need to point to another table. It could also hold a function, like this:

-- Now, we'll change the way t2 handles failed lookups in t1 so that it always returns the key that was asked for.
t2.__index = function (t, k)
return k
end

print(t1.a)
print(t1.b)
print(t1.c)

And now we get:
3
b
c

It is actually possible to make t2 be the metatable:
-- What happens with this?
t2.__index = t2
t2.d = 6

print(t1.a)
print(t1.b)
print(t1.c)
print(t1.d)

The results:
3
nil
nil
6

In conclusion, lua is neat.

19 thoughts on “Lua metatable examples

  1. I just designed a Lua program that acts as a nanny for my children when I’m not around. I did it in 10 lines of code.

    Bust seriously.. Sorry about ducking out on your fun Friday, had a bit of an emergency back home I had to contend with in a hurry.

    Take care and don’t forget to write.

  2. Wow, it still seems a bit voodoo. It seems, as if a metatable were a function.

  3. I checked out your link and now it seems more clear:

    The use of the __index metamethod for inheritance is so common that Lua provides a shortcut. Despite the name, the __index metamethod does not need to be a function: It can be a table, instead. When it is a function, Lua calls it with the table and the absent key as its arguments. When it is a table, Lua redoes the access in that table.

  4. Yeah, I wrote this post after spending many hours playing with
    metatables until I finally felt like I understood them. It took me a
    long time before the double-indirection seemed logical.

  5. Can you name other uses of double indirection, or it is restricted to metatables?

  6. Double indirection shows up all over the place. In this case, a failed lookup on the first table goes to the metatable. That's the first indirection. The second indirection happens when the metatable uses the __index to handle the lookup.

    Filesystems that use inodes can use double indirection too. That might be a good place to study it.

  7. I have experimented a little bit with metatables, and found it intresting that the values in metatables doesn't show up in foreach.

    a={apple=”green”}
    b={cucc=”asas”}
    setmetatable(a, {__index = b})
    for k,v in pairs(a) do print(k,v) end
    print(“——“)
    print(a.cucc)
    print(a.apple)

  8. I don't know whether you heard about it, but there's a nice opensource 3d engine using Lua. (You don't have to write C code at all.) Physics simulation is integrated as well (ODE). It's called Apocalyx. It ships with a handful of demos. (They're quite straightforward, you can learn the usage of the engine just by modifying them.) It's very easy to use, and that is the main reason I'm learning Lua.

  9. The use of the __index metamethod for inheritance is so common that Lua provides a shortcut. Despite the name, the __index metamethod does not need to be a function: It can be a table… What to do?

  10. From your examples I can easily learn. Also the way to present the example is very nice.
    Also I have got clear ideas about the metatable.
    by thoi trang

Comments are closed.