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.

  • http://www.just-another.net Ben S.

    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.

  • zslevi

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

  • zslevi

    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.

  • http://blog.tplus1.com Matt Wilson

    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.

  • zslevi

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

  • http://blog.tplus1.com Matt Wilson

    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.

  • zslevi

    I meant double indirection in Lua.

  • http://blog.tplus1.com Matt Wilson

    Oh — sorry, I don't know of any other examples.

  • zslevi

    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)

  • zslevi

    It produces the following output:

    apple green
    ——
    asas
    green

  • zslevi

    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.

  • http://blog.tplus1.com Matt Wilson

    Wow — that 3d engine sounds really neat! Thanks for the tip. I will
    have to look at that.

  • http://www.uk-cheapest.co.uk Buy web hosting

    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?

  • thoi

    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

  • thoi

    I really thank to you for explaining in such a way. Good way of presentation.
    by thoi trang

  • http://www.uk-cheapest.co.uk Domain Name Registration

    Thanks for sharing the post.

  • http://www.stretchmarkscare.com/ stretch mark creams

    Thanks for posting Lua metatable example.I was looking for it……….

  • williamrobert30

    Thanks for posting Lua metatable example.I was looking for it……….

  • http://caoch.net/ coach outlet

    thank you for your post,nice,i am appriciate what you said!