I was wondering, what exactly is the difference between dictionaries and metatables. I have tried looking online for an answer to this question, but found nothing.
From what I can tell, metatables are just a complicated dictionary, but correct me if I’m wrong!
Dictionaries are a “variant” of tables that use keys that are not contiguously numerical, or otherwise are not in a list. A metatable is a table for metamethods which are invoked if certain conditions are met and you do not use a raw function. They’re two separate, incomparable things. A metatable, in practice, is a dictionary of metamethods though.
local dictionary = {
["foo"] = "bar"
}
local mt = {}
local t = setmetatable({}, mt)
mt.__index = dictionary
print(t.foo) -- bar
print(rawget(t, "foo")) -- nil
In the above example, I used the index metamethod. Key foo with value bar exists in dictionary but not in table t. Table t has a metatable with the index of dictionary. Since key foo does not appear in table t, it invokes the __index metamethod. That’s why the first print gives back a value that doesn’t exist in the original table. The second print is to get an index in the table without invoking a metamethod. Key foo does not exist in table t and no metamethods are invoked, so nil.
If you know about dictionaries, then a metatable IS a dictionary used for a special purpose (to hold metamethods). Both dictionaries and metatables are covered in links posted by WooleyWool.
The word “meta” means that something refers to itself. So, consider functions that operate on a dictionary. If you attach those functions to the dictionary itself (for use on itself), then they would be methods (aka functions) of that dictionary for use on the dictionary, i.e., metamethods. The table that keeps track of those for a given table is called a metatable–a table that’s associated with another table and contains metamethods (or references to metamethods).
Meta-stuff usually isn’t something to worry about unless you are trying to learn OOP. It’s easier to understand in that context anyway.
Something more concrete:
This kind of thing is possible with dictionaries.
local dict = {[1]='Hi', [2]='there'}
function dict.printContents()
for _,val in pairs(dict) do
print(val)
end
end
function dict.sayHi()
print(dict[1], dict[2])
end
dict.printContents()
dict.sayHi()
Those functions are “attached” to the dict and can be run somewhat like other functions.
The output here is this:
Hi
there
function: 0x8386114df31592eb
function: 0x887e25f5ed1da4ab
Hi there
Having those functions scattered around inside the main table isn’t ideal, so Lua has a special metatable feature where it associates another table with the dict table (Actually, most any Lua obj can have a metatable) where it can store these kinds of user-defined functions (and other stuff, like built-in behaviors). It’s a mechanism for extending Lua objects or customizing their behavior to better suit your needs. That’s the metatable, essentially. This is very oversimplified, but maybe it’s enough to help wrap your head around the concept while you look at more detailed explanations.