Difference between metatable classes and functions

Hello! I’ve recently been trying to push myself more into metatables, as I find them very interesting! I’ve been primarily looking at creating classes with metatables, but it’s lead me to a question Google hasn’t been able to answer for me.

Why do people use metatable classes instead of functions? From what I’ve seen, metatable classes are really only useful for inheritance, which isn’t even used in many examples of metatable classes I’ve seen out there!

For example, I’ve seen people do things like:

local tbl = {}
tbl.__index = tbl

function tbl.new(name)
    local newTbl = {}
    
    newTbl.name = name

    return newTbl
end

function tbl:SetName(newName)
    self.Name = newName
end

local object = tbl.new("This is a name!")
object:SetName("This is a NEW name!")

When instead, you can just do something like this:

function newNameTable(name)
    return {
        Name = name
    }
end

function changeName(nameTable, newName)
    nameTable.Name = newName
end

local NameTable = newNameTable("This is a name!")
changeName(NameTable, "This is a new name!")

This is obviously a VERY bad example, but I’m hoping you get the gist?

Once again, I’m just wondering why do people use metatable classes instead of functions when they don’t actually need any sort of inheritance.

1 Like

It’s mostly for organization purposes and this is how it’s done in other languages anyway. There are 4 pillars of OOP, and one of them is encapsulation. Encapsulation is all about encapsulating the data of an object together, and exposing the functions that act on objects as methods in the class is part of that. Additionally, if you didn’t expose the functions as methods, how do you plan on exposing them to other scripts that might need them?

2 Likes

For exposing functions, could you not just use a ModuleScript? ModuleScripts and functions are used very often. I’m just not seeing why people use metatable classes without using inheritance since that’s the only benefit I’ve noticed in them.

With metatables they are already exposed, you can just do tbl_instance:SetName on an instance of tbl since SetName doesn’t exist in the instance, so Lua(u) falls back to tbl where it does exist. Now, how would you do that elegantly with the methods detached?

1 Like

Both do the same thing quite well though, do they not? Are metatable classes more superior? Why or why not? Are there any major reasons to use them instead of functions?

As I mentioned, one of the 4 pillars of OOP is encapsulation, by making them detached functions you are going against encapsulation.

1 Like

And what’s the point in encapsulation? It doesn’t seem TOO important.

All of the pillars are important, you don’t really have OOP without all 4.