Blog
About Me
Short rant about lua constructor
Simon Creek
2022-04-11 08:12

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.