Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

What are metatables, what is their use and why should I use them?

Asked by 3 years ago

I consistently see people using this thing called metatables and see a lot of __

This is an example of what I've seen:

local tab = {}
setmetatable(tab, tabl)

Just like the title says: What are metatables, what is their use and why should I use them?

All help is appreciated!

1 answer

Log in to vote
2
Answered by
imKirda 4491 Moderation Voter Community Moderator
3 years ago
Edited 3 years ago

Well so i am not pro at metatables, but i know some good uses for them, it is used a lot for Object Oriented Programming.

So to create a metatable as you said you use setmetatable() function, but first you need to have 2 tables, one you want to set metatable to and one handling the metatable functions, i will explain here so you won't be that confused.

So for example you have a table:

local myTable = {}

And you want to add value in it, you would do this:

myTable["myValue"] = 5

But let's say you also want to do a specific function when adding the value instead of just putting the number in it, you want to do more stuff for example. Here is when you can use metatable, those __ are built in functions that you can use, here are some of them and how you can use them.

So first you need to make a new table which will be our metatable

local metatable = {}

And now here are the functions: [EDIT: You can later find them on the devforum instead of this mess] __index(table, index) Fires when table[index] is indexed, if table[index] is nil. Can also be set to a table, in which case that table will be indexed. __newindex(table, index, value) Fires when table[index] tries to be set (table[index] = value), if table[index] is nil. Can also be set to a table, in which case that table will be indexed. __call(table, ...) Fires when the table is called like a function, ... is the arguments that were passed. __concat(table, value) Fires when the .. concatenation operator is used on the table. __unm(table) Fires when the unary – operator is used on the table. __add(table, value) The + addition operator. __sub(table, value) The – subtraction operator. __mul(table, value) The * mulitplication operator. __div(table, value) The / division operator. __mod(table, value) The % modulus operator. __pow(table, value) The ^ exponentiation operator. __tostring(table) Fired when tostring is called on the table. __metatable if present, locks the metatable so getmetatable will return this instead of the metatable and setmetatable will error. Non-function value. __eq(table, value) The == equal to operator¹ __lt(table, value) The < less than operator¹; NOTE: Using the >= greater than or equal to operator will invoke this metamethod and return the opposite of what this returns, as greater than or equal to is the same as not less than. __le(table, value) The <= operator¹; NOTE: Using the > greater than operator will invoke this metamethod and return the opposite of what this returns, as greater than is the same as not less than or equal to. __mode Used in weak tables, declaring whether the keys and/or values of a table are weak. NOTE: References to Roblox instances are never weak. Tables that hold such references will never be garbage collected. __gc(table) Fired when the table is garbage-collected. NOTE: On Roblox, this metamethod is disabled. __len(table) Fired when the # length operator is used on the Object. NOTE: Only userdatas actually respect the __len() metamethod in Lua 5.1.

This is just stolen from the devforum page

But here is explanation of how it works:

To create a function like that you need to take the metatable:

local myMetatable = {}

function myMetatable:__newindex()
    print("metatable has been newindexed!")
end

function myMetatable:__index()
    print("__index has been used!")
end

So you don't know now what is it BUT the output will explain this very quickly

So first let's set the metatable

setmetatable(myTable, myMetatable)

And now here it comes

print(myTable["car"])

So this is when the __index function that we put into the metatable fires, whenever the table is indexed, and we attached function to it which prints it so the output will be:

2:00:00 > __index has been used!

This is same just like __newindex and most of the other __ functions works. So let's use __newindex since we put it into the metatable too! It fires whenever the table is indexed with a value like this:

myTable["car"] = true

--Output
2:00:00 > myTable has been newindexed!

ASAIK instead of adding the ["car"] value into the table, it will fire the function so if you print it:

myTable["car"] = true
print(myTable['car'])

Output should be:

2:00:00 > myTable has been newindexed!
2:00:00 > nil -- Because instead it fired the function

And you can attach also other functions like __add function which will fire whenever you do

+myTable

Although you will need to have other arguments there. So for example:

print( 5 + myTable)

This is when it won't error and it will fire the __add function.

You can create mutliple tables like that:

local function CreateTable()
    return setmetatable({}, myMetatable)
end

local myNewTable = CreateTable()

myNewTable['car'] = true

--Output
2:00:00 > myTable has been newindexed!

Also i didn't say but here are what the arguments are for it:

myNewTable['car'] = true
function myMetatable:__index(
    -- First argument is the index, in this case it's 'car'
    -- Second argument is the value given, in this case it would be 'true'
)

Since i used :, then the self is automatically defined, if you use . then it's

function myMetatable.__index(
    -- Self,
    -- 'Car',
    -- 'true'
)

Those were the basics, this is just how i use it, i am not explaining it that good but i think something is understandable, here are some sources you could use:

Devforum page about metatables

About OOP

0
Love the post, but however, are you saying that these meta tables have prebuilt functions we can access inside the keys, or are they write only. Nckripted 580 — 3y
0
Those are built functions in the metatables that must be put inside the metastable with __ symbols if this is what you mean. imKirda 4491 — 3y
Ad

Answer this question