I was reading the chapter "Object-Oriented Programming" in "Programming in Lua" on https://www.lua.org/pil/16.html.
In that example, they create this "constructor":
Account = {balance = 0}
function Account:new (o)
o = o or {} -- create object if user does not provide one
setmetatable(o, self)
self.__index = self
return o
end
I've made some "sintetic benchmarks" on Linux with a simple time in a script with 10 million operations like these one. Defining Account.__index = Account outside the table initialization is 200ms faster.
My question is, why set the self.__index inside this function that will be executed every time this function is called if we can define outside and execute a single time? Heritage maybe?
EDITED:
Thank you luther for the answer, I'll just create an example here for everyone with this doubt:
local a = {}
a.__index = a
function a:foo()
return 'foo'
end
function a:new(o)
print(self)
o = o or {}
setmetatable(o, self)
-- self.__index = self
return o
end
local b = a:new()
-- b.__index = b
function b:bar()
return 'bar'
end
local z = a:new()
print(z:foo()) -- this will work
local y = b:new()
print(y:foo()) -- attempt to call method 'foo' (a nil value)
print(y:bar()) -- attempt to call method 'bar' (a nil value)
Of course y will have a metatable with b as that table, but b doesn't have an __index entry, this entry is only inside b's metatable.
If you still want to avoid declaring __index inside the "constructor", you'll need specify this in every derivated prototype, or "subclass".