local myTable = {}
setmetatable(myTable, myTable)
myTable.__index = function()
print("fired")
end
print(myTable[1])
In the code, I set myTable to a metatable, which is it self. How does __index fire? I know it fires if you try to index some thing nil in a table and if I don’t use setmetatable, will __index ever fire?
I’ve seen people doing this:
local Object = {}
Object.__index = Object
setmetatable(Object, Object)
Object.__index = function()
print("fired")
end
print(Object[1])
From my understanding of metatables, I know that the code is setting a metamethod to the table. Then, it is using the setmetatable. The second argument of setmetatable requires a metatable. So has Object became a metatable because of using a metamethod on it?
Metamethods behaviors are bound to setmetatable. If you don’t use setmetatable, no metamethods are invoked. If you don’t use __index, it will stay to default method.
It will only be a metatable if you set it as another table’s metatable. If you’ve set some metamethods but it isn’t the metatable of any other table, then those metamethods won’t do much. (In your example, though, you do set it as its own metatable so the metamethods will be invoked)
local Object = {}
Object.__index = Object
setmetatable(Object, Object)
Object.__index = function()
print("fired")
end
print(Object[1])
In this line:
local Object = {}
Object.__index = Object
setmetatable(Object, Object)
How can I set Object to it self? Is it because it’s a table and includes these {}? Because the second argument of setmetatable should be a metatable like {}. Correct?
A metatable is still a table, like any other table. When using setmetatable() you’re just assigning a table to act as the metatable for another table, meaning it will look in that table for any metamethods that would alter the normal functionality of the table.
To be set as a metatable the only requirement would be that it has a datatype of table.
A metatable is the name given to a table which contains metamethods (such as __index) there is no difference in terms of how the table is used. It is simmilar to how an array is the name given to tables which contains only numeric indexes.
Metatable is just a name for the second argument of setmetatable and the return of getmetatable
You can set any table as the metatable, including itself, but it wont do anything unless it contains metamethods. The important thing to take from this is Lua will look in the metatable for a metamethod when it needs to, if it finds one then it is fired, otherwise the table will be ignored.
Any table can be used as a metatable, but nothing happens unless it contains metamethods
Finally, myTable[1] will not trigger __newindex only __index. The metamethod __newindex will only be triggered when trying to assign a new index. eg. myTable[1] = 'Foo' If index 1 already exists then nothing will happen, but if index 1 is nil then __newindex will be fired.
__index is triggered when getting a nil index, __newindex is triggered when setting a nil index