How does setmetatable() work and why the metatable is needed in the linked list in lua

2.2k views Asked by At

I'm learning how Lua's metatables work in OOP, and I am confused of the code I read from the object orientation tutorial on lua-users wiki. Could someone helps to explain the following questions? Thanks.

Question 1: The wiki's explanation: Here we add a metatable to the class table that has the __call metamethod, which is triggered when a value is called like a function. We make it call the class's constructor, so you don't need the .new when creating instances.

(1)How does the __call get called in the example so the constructor is called?
(2)Does "cls" refer to "MyClass?"

setmetatable(MyClass, {
  __call = function (cls, ...)
  return cls.new(...)
end,
})

Question 2: What does {} from the following code refer to?

function MyClass.new(init)
  local self = setmetatable({}, MyClass)
  self.value = init
  return self
end 

**Here is the Complete code:

local MyClass = {}
MyClass.__index = MyClass

setmetatable(MyClass, {
  __call = function (cls, ...)
  return cls.new(...)
end,
})

function MyClass.new(init)
  local self = setmetatable({}, MyClass)
  self.value = init
  return self
end

function MyClass:set_value(newval)
  self.value = newval
end

function MyClass:get_value()
  return self.value
end

local instance = MyClass(5)
-- do stuff with instance...
1

There are 1 answers

0
InputUsername On BEST ANSWER

Question 1:

setmetatable(MyClass, {
  __call = function (cls, ...)
  return cls.new(...)
end,
})

This sets MyClass's metatable to a table which defines the __call metamethod. Because of that, you can 'call' MyClass (newObj = MyClass(<args>)). In the metamethod, cls refers to the table that is called, in this case it refers to MyClass.

Question 2:

function MyClass.new(init)
  local self = setmetatable({}, MyClass)
  self.value = init
  return self
end

{} is syntax for a table literal, which creates a new table (an empty one in this case). The MyClass table is set as the metatable for a new table. Then this new table is assigned to self.

More about metatables can be found here: https://www.google.com/?gws_rd=ssl#q=lua+metatables as suggested by Anderson Green in the comments.