Sorry it's not quite a specific question.
In the "Programming in Lua, 4th edition" one can see the following code :
Account = {balance = 0}
function Account:new (o)
o = o or {}
self.__index = self
setmetatable(o, self)
return o
end
My confusion is the line
self.__index = self
This means that Account
becomes its own __index
only on creation of an instance :
a = Account:new()
which is confusing if you think about it. I know that it is done to easily increase the depth of inheritance so you can do :
AccountGold = Account:new({cashBackPercentage = 5})
AccountPlatinum = AccountGold:new({personalSupport = true})
but to me this
Account.__index = Account
looks more readable.
Even more confusing. For example, look at the yui library:
local Button = setmetatable({
__call = function(cls, args) return cls:new(args) end
}, Widget)
Button.__index = Button
function Button:new(args)
self = setmetatable(args, self)
self.text = self.text or ""
self.align = self.align or 'center'
self.valign = self.valign or 'center'
self.active = false
if not self.notranslate then
self.text = T(self.text)
end
return self
end
Look at this :
self = setmetatable(args, self)
which reads to :
Button = setmetatable(args, Button)
which means that every time new instance is created the Button
table is changed.
Is it like a common practice ? Could you comment on this please ?
What you read is incorrect, self = setmetatable(args, self)
doesn't change Button
, it just overwrites the parameter self
to the return value of setmetatable
, so it is equivalent to the following code:
local t = setmetatable(args, self)
t.text = t.text or ""
...
The implicit parameter self
is dynamic, its value depends on how the function is invoked. For Account:new(....)
, self
is Account
, for AccountGold:new(....)
, self
is AccountGold
, so that you can achieve inheritance with a single function.
self.__index = self
is cheap, but if you need to strictly control the exposed members, you should create a separate metatable.