View Single Post
08-16-05, 10:22 AM   #10
Littlejohn
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Jun 2005
Posts: 90
And now the Lua tour de force: metatables.

Why copy tables at all? The copy wastes memory (especially if you have large read-only data sets). Even worse, once you copy a table, any changes made to the original won't show up in the copy, so you have to manually code the update logic. This can get really hairy if you allow people to over-ride options after the copy.

Lua is built on tables so it has a fancy (and fast!) way to inherit values from one table to another without making a copy: metatable.__index.

I'm not going to talk about metatables much. Metatables are a little bit like object classes in Java or Python. Setting a table's metatable basically changes the class of the table from "normal Lua table" to your custom class.

The following code changes the "Player_options" table so it will inherit all the values from the player's Class_options table.
Code:
local _, class = UnitClass('player')

Player_options = {a = 1, b = 2, c = 3}
Class_options = {
    WARRIOR = {d = 'foo', e = 5, f = 6},
    ROGUE = {d = 'bar', h = 10, i = 100}
}

setmetatable(Player_options, { __index = Class_options[class] })

print('a', Player_options.a) -- get 'a' from Player_options
print('d', Player_options.d) -- get 'd' from Class_options.WARRIOR

-- you can dynamically change the metatable. if the metatable
-- is shared among several tables, the change immediately affects
-- all of them.

getmetatable(Player_options)['__index'] = Class_options.ROGUE

print('a', Player_options.a) -- get 'a' from Player_options
print('d', Player_options.d) -- get 'd' from Class_options.ROGUE
You can assign values to Player_options fields just like a normal Lua table. Since I've only defined the __index behavior, all assignments go directly into the Player_options table. The inherited Class_options table is never modified. I think this is a nice feature: Player_options over-ride inherited options and you can update Class_options without worrying if someone changed one of the inherited options.
  Reply With Quote