What is a Metatable?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I will lern the OOP (Object Oriented Programming)

  2. What is the issue? Include screenshots / videos if possible!
    I don‘t know what are metatables.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I look for solution in Developer Hub, but don‘t find any Soution.

Please, i want only a example, thanks to read my topic.

5 Likes

Metatables are simply tables but with extra flexibility. Earlier, I asked for a visual representation of a metatable. They are described like this:


Advantages

  • Metatables are flexible
  • Can do better than weak tables

Disadvantages

3 Likes

Here is a helpful tutorial on how to use OOP.

2 Likes

How can i use metatables in my scripts, for make something and when do I have to use it???

I commonly use the __index metamethod for adding a default value to my table if something doesn’t exist or to return true etc. Here’s a little example:

local monsters = { --Our table of monsters
    Troll = {
        Damage = 10;
        Health = 100;
    };
    Yeti = {
        Damage = 20;
        Health = 150;
    };
}

setmetatable(monsters, {
    __index = function() --It has to be a function!
        return { --return the default value
            Damage = 5;
            Health = 50;
        }
        end;
})

print(monsters["Troll"].Damage) --10
print(monsters["Yeti"].Damage) --20
print(monsters["Loc Ness Monster"].Damage) --5
12 Likes

Metatables have metamethods which are called under certain conditions. For example take the metamethod “__index”, this is commonly used to guard against any typos or set a default value for undefined values in a table. Take a look at this example from the Roblox Lua Style guide.

local MyEnum = {
    A = "A",
    B = "B",
    C = "C",
}

setmetatable(MyEnum, {
    __index = function(self, key)
        error(string.format("%q is not a valid member of MyEnum",
            tostring(key)), 2)
    end,
})

Since __index is only called when a key is missing in the table, MyEnum.A and MyEnum.B will still give you back the expected values, but MyEnum.FROB will throw, hopefully helping you track down bugs more easily.


There are many more metamethods you can read about here which all serve a different purpose.

2 Likes

@RetributionVI, your example is very ggod but the example of @return_end1 is easier to understand.

1 Like

@RetributionVI mentioned a tutorial that I found very useful when trying to understand OOP. I think it’s worth a look, although it may be slightly confusing.

Lets look at one of the definitions of the word meta: “concerning or providing information about members of its own category”

Taking this into context, a good way to explain metatables is they are tables that are meant to to extend and/or provide details about a table. Metatables themselves don’t do anything. They are just ordinary tables. Its only when you use the setmetatable function that it operates like a metatables.

Metatables allow you to override the behaviors of an existing table. That is what metamethods are for. They serve as the entry point for this. The current amount of metamethods can override most behaviors from performing math operations of two tables, to calling them like a function or indexing a nil table.

This kind of behavior overriding is what really makes OOP useful. For example, when making an OOP object, the internal OOP variables of the table can store values specific to that object, while you can use the __index metamethod for when it is nil to try and refer back to the functions and properties global to all objects in the script/modulescript it was created in.

A list of the available metamethods and what they do can be found here: https://developer.roblox.com/en-us/articles/Metatables

2 Likes

Ok thanks for say this, can you send me this tutorial?

Very good explained. Thank :smile:

It does not. If __index is a function, it will be called for a nil index in the real table and expect a value to be returned as it is a callback. It can also be a table though so in the case that an index in the real table is nil, it performs a lookup in the index table.

I would especially return a table in your example because what you provided is relatively expensive. You construct a new table per nil index. Templated so the expense is lowered but still expensive nonetheless. You can just return a default table and this will work fine.

__index = {Damage = 5, Health = 50}

Better yet, if a table index does not achieve your intended function for whatever reason (all nil indexes reference the same default table), then implement memoisation. This is so that the call does not have to be repeated later and end up being expensive to run.

local monsters = {
    Troll = {
        Damage = 10;
        Health = 100;
    };
    Yeti = {
        Damage = 20;
        Health = 150;
    };
}

setmetatable(monsters, {
    __index = function(self, index)
        if not self[index] then
            self[index] = {Damage = 5, Health = 50}
        end

        return self[index]
    end
})

If you occupy __newindex, change to use raw operators.

3 Likes

If i can make this:

local Object.__index = something

,then what does that mean( i see Egomoose write it, but don‘t understand this thing)

That is incorrect syntax. You can not make that.

1 Like

I think you’re reading the code the wrong way. Variable declarations do not work like that. When it comes to OOP metatables, they are set up like this:

local Main = {}
Main.__index = Main

This constructs a table called Main and adds a __index member to it assigned to the table Main. When setmetatable is called, Main is passed and automatically handles the metamethods. This was addressed on your other thread (please maintain a single thread at one time if it’s of the same topic).

4 Likes