The Good Stuff of Day 2, Lua Metatables

The “Seven Languages” books (and probably all of the “Seven in Seven Weeks” series) is more a collection of amuse bouche (amuse bouches? amuses bouche? amusi bouchi? nahh) than of entrees or even appetizers. And that makes sense because there’s no way to fit all the details on seven languages in one book. But it also means you read a section and find yourself going “What the heck was that? It was really tasty, but I really want more.”

So it was when I read the section on metatables. Sure there is some info on metatables in Seven More Languages but I really wanted more. I found the Lua book at http://www.lua.org/pil/13.html to be very useful in augmenting it. All of chapter 13 is devoted to metatables and metamethods. I also figured out why the object-oriented stuff got put in Day 2.

So, metatables!

The Amuse Bouche

All tables have metatables, but by default the metatables are empty. You can get to a metatable for a table using getmetatable(sometable) . And, hopefully not surprisingly, you can change a metatable for a table using setmetatable(table, new_metatable) .

So, how do you create a new metatable? And what can go there?

Recall the Florida info table:

stateFL = {
    capital = 'Tallahassee',
    bird = 'mockingbird',
    population = 19890000
}

Trying to print it just gives its address, as is done in many languages.

> print(stateFL)
table: 0050D708

But you can create a function to convert the table to a proper string:

function to_string(t)
    local result = {}
    for k, v in pairs(t) do
        result[#result + 1] = k .. ": " .. v
    end
    return table.concat(result, "\n")
end

Of course, you could just print the table using this new function print(to_string(stateFL)) but that’s not noteworthy. Instead, assign the __tostring function of the metatable. One way to do this is to create a metatable with the function as its only member and make it the metatable of stateFL

mt = {
   __tostring = to_string
}

setmetatable(stateFL, mt)

Then printing the table does the expected thing:

> print(stateFL)
bird: mockingbird
capital: Tallahassee
population: 19890000

There are lots of operators which can be overriden using metatables, including +, -, /, *, <, <=, and ==. You can also override the action when reading and writing to the table to provide different default values, tracking of all changes to the table, and read only tables.

Even though Lua has a mechanism for object oriented programming, you can use metatables to quickly create classes. The Lua book on-line shows how to create a Set class with just metatables. I’ve got a copy in the file Set.lua on my Github account.

The Set class is pretty cool and it points out another feature of Lua, that it’s a prototype rather than object oriented language. Since the first book covered Io, another prototype language, that’s not a new idea for me, but I’ll still finish up day 2 with finding out how Lua handles prototyping.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: