Metatables, metamethods for dummies

Ah yes, metatables something that new scripters have a hard time grasping? Am I wrong? If so then prove me wrong. So here’s a sample code for the simplest metamethod

local Table = {bobux = math.huge} -- Our regular table, lol ugly dictionaries
local MetaGet = {bobux = math.min, abc = "def"} -- Reference Table
local Meta = {} -- table to attach to "Table"
Meta.__index = MetaGet

print(Table.abc) -- nil
setmetatable(Table, Meta) -- now whenever you index something nil with Table, it would look in the MetaGet table for the value with that index.
print(Table.abc) -- "def"
print(Table.bobux) -- math.huge, since Table.bobux is valid, it'll return that instead of math.min which is a function

So as it can be seen, whenever u try to index something that is nil, it’ll invoke the __index metamethod. Here’s a second example of the __index metamethod.

print(setmetatable({}, {
    __index = function(self, index) -- self is basically the table that got invoked, so in our case, it is the 1st argument in the setmetatable above and index is what u tried to index self with.
        return index
    end
}).bruh) -- bruh

So basically the reason that metatables are so special is because that they have those metamethods that get invoked when you interact with them in a specific way. Like __index. So there is also getmetatable that is used to get a metatable. It isn’t much use because setmetatable returns the 1st argument which is a table.

local tubl = {}
local alsotubl = setmetatable(tubl, {__index = {a = 1, b = true}})
local alsometatable = getmetatable(tubl)

print(tubl, alsotubl, alsometatable) -- table: [hexadecimal memory address], first 2 would be the same but the third is actually the metatable(2nd arg of setmetatable)
print(tubl.a, alsotubl) -- 1, true

Now I’ve used the __index metamethod way too many times, lets switch to the __newindex one. __newindex gets invoked when ur trying to add a new index to the metatable(table returned from setmetatable). Since Lua strings are tables, I’ll show how it errors when ur trying to add a new index

local str = {
    __newindex = function(self, index)
        error(string.format("attempt to index string with %s", index))
    end
}

local stringobj = setmetatable({}, str)
print(stringobj.hi) -- would invoke __index if it was there

stringobj.hi = "moment" -- blah blah : attempt to index string with 'hi'

So there are more metamethods you could practice with, they provide the necessary information about how the other metamethods work. metatables in dev hub. It is recommended to click the next link because it teaches more about metatables than I do more metatables. Mine was just trying to get people who couldn’t grasp metatables by reading that post.

11 Likes

I feel like that’s a confusing way of describing how string methods work in Lua. Strings are strings, not tables. You can have a metatable without being a table (see newproxy).

4 Likes

Ah I see, I keep forgetting what newproxy() is. Pretty useful info ig