Object-oriented programming (OOP) can be confusing; Although I use it, __index and metatables are just plain confusing, even to me. From what I know, __index is one of the “metamethods” in a table’s metatable, which stores info about its contents, such as its variables and any tables nested within it.
In your example, outside of the .new() constructor, you’re defining the “base class”, which contains all of the class’ functions and variables. Here, __index’s contents matches what the table contains, since they’re one and the same.
However, in class.new()
, a brand new table is created (which you already know). This new table is empty, but it uses setmetatable() to set the new table’s metatable to the original class’s one, and since its __index metamethod was set to the class’s contents, it will check that table if it can’t find something in the new object’s table.
c:Something()
works because you linked the new table to the original using its metatable; When you call that function, Roblox sees if the new object contains c.Something
. If the metatable wasn’t set, this would produce an error, but Roblox checks the table stored in __index, finds Something()
there, and executes that instead.
If you defined a new function in the .new() constructor with the same name, Roblox would use that instead of falling back on the class’s own. Interestingly, this is how programmers make classes that “inherit” from each other, which is too confusing for me…
Info about calling functions using colons and periods...
I know you didn’t ask about this, but I wanted to add that functions called using a colon (like c:Something()
) call the function with a reference to the object as its first parameter (as the variable “self”). So, class.Something(c)
should do the same thing.
I hope this wasn’t too confusing and was useful; My mind can’t write as well-written sentences as it used to, but I wanted to explain what I knew about that metamethod and OOP.