Lua object constructor
Lua's constructor is very misleading in official web book. This is an example
which resembles official book's account example which sets values to self
.
local FieldState = {
row = 10,
col = 10,
field = {},
}
function FieldState:new()
local o = {} -- Newly created object instance
setmetatable(o,self)
self.__index = self
-- Assign new empty field
self.field = utils.empty_2d_array(
self.row,
self.col,
block_state.blank
)
return o
end
The problem is this code is setting value to self not to o. When you're using
multiple objects, the field will be shared through objects which might be
useful but can be unintended behaviour for many, namely a static variable.
Always set a value to o
when the value should be unique. If not, method
will try to execute "__index" operation and get original prototype's value.
Metatable is kinda exotic concept in the first place
Metatable is a confusing for newcomers. Simply put, metatable is conceptually similar to operation overload in c++. You can overload (overwrite) several operations with metatable.
Operations like __add or __sub are intuitive but __index is not while it might be the first operation you might encounter. __index is like an aliasing which maps every lookup operation for the bound table.
For example there are two tables called A and B
A has following attributes
- [Field] second
B has following attributes
- [Field] first
- [Field] second
- [Associated method] Sum -> Uses self.first and self.second
With setmetatable(A,B)
B is bound to A as metatable ( A points B, A -> B ).
Furthermore user can override __index operation with simply assigment as
B.__index = B
which means B's indexing should reference B.
Finally user can index B's Sum method from table A with syntax like B:Sum()
.
The caveat is that __link operation only works when the given key or say lookup
is not present in original table. Thus B:Sum()
will use A's first
without
__index and B's second
with __index operation.