I'm learnig Lua and how OOP in Lua works and I've seen this code in the reference
function newAccount (initialBalance)
local self = {balance = initialBalance}
local withdraw = function (v)
self.balance = self.balance - v
end
local deposit = function (v)
self.balance = self.balance v
end
local extra = function ()
if self.balance > self.LIM then
return self.balance*0.10
else
return 0
end
end
local getBalance = function () return self.balance self.extra() end
return {
withdraw = withdraw,
deposit = deposit,
getBalance = getBalance
}
end
This seems to work fine but when I print the address of a the private function before the return like this
...
print(extra)
return {
withdraw = withdraw,
deposit = deposit,
getBalance = getBalance
}
and then create two accounts
account1 = newAccount(1)
account2 = newAccount(1)
I get two different address values
function: 00D2B290
function: 00A22040
Is this OK? I understand this as the same function being instanciated once per object constructor, wouldn't be more efficient if the same function was instanciated once and then refencenced? Or is this something lua handles this way?(I've been coding in C recently where this could be a problem I guess)
I know that I could make this
local function private_extra(self)
if self.balance > self.LIM then
return self.balance*0.10
else
return 0
end
end
local function newAccount (initialBalance)
local self = {balance = initialBalance}
local withdraw = function (v)
self.balance = self.balance - v
end
local deposit = function (v)
self.balance = self.balance v
end
local getBalance = function () return self.balance private_extra(self) end
return {
withdraw = withdraw,
deposit = deposit,
getBalance = getBalance,
}
end
and it could work the same way and the address of the function would be the same when the constructor is called more than once. Would this be a better approach talking about efficiency? Although I think that it makes the code uglier.
CodePudding user response:
In Lua, a function object must refer to both the closure environment and the function's code. In your example, the two extra
functions have different addresses, because they are two different closures. In other words, each one refers to a different self
variable. However, they do both refer to the same function code, so there shouldn't be a significant impact on performance.
I'm not even sure why PiL uses a self
variable in newAccount
, since it returns a whole different table. Private data can all be stored in local variables, and anything you want public can be in the returned table.