Lua - Tables as Objects



Lua supports Object Oriented Programming by the concept of Table and first class functions. An object is having a state and functions to modify the state. In similar fashion, table can have state and function. But two tables with same values are different objects. Using metatables, we can create table which can act as a class template.

Tables, like objects, have a life cycle that is independent of who created them or where they were created.

Example - Define an Object as a Table

Consider a case of Rectangle Object. Let Rectangle has length, breadth as its state and a function area to get the computed area.

main.lua

-- create a Rectangle class
Rectangle = {length = 10, breadth = 5}

-- compute area of Rectangle
function Rectangle.area()
   local area = Rectangle.length * Rectangle.breadth
   return area
end

-- create rectangle object
r1 = Rectangle

-- compute and print area of Rectangle object
print(r1.area())

-- modify length
r1.length = 20

-- compute and print updated area of Rectangle object
print(r1.area())

Output

When the above code is built and executed, it produces the following result −

50
100

Example - Using global object to access the same Table

Problem with above code is that in area() function, we're using Rectangle as a global object. If Rectangle is set as nil, then code will fail.

main.lua

-- create a Rectangle class
Rectangle = {length = 10, breadth = 5}

-- compute area of Rectangle
function Rectangle.area()
   local area = Rectangle.length * Rectangle.breadth
   return area
end

-- create rectangle object
r1 = Rectangle

-- compute and print area of Rectangle object
print(r1.area())

-- set Rectangle as nil
Rectangle = nil

-- compute and print area of Rectangle object
print(r1.area())

Output

When the above code is built and executed, it produces the following result −

50
lua: main.lua:6: attempt to index a nil value (global 'Rectangle')
stack traceback:
   main.lua:6: in field 'area'
   main.lua:20: in main chunk
   [C]: in ?

Example - Using self object to access the same Table

Now to resolve this dependency, we can use self keyword to represent the current object.

main.lua

-- create a Rectangle class
Rectangle = {length = 10, breadth = 5}

-- compute area of Rectangle
function Rectangle.area(self)
   local area = self.length * self.breadth
   return area
end

-- create rectangle object
r1 = Rectangle

-- compute and print area of Rectangle object
print(r1.area(r1))

-- set Rectangle as nil
Rectangle = nil

-- compute and print area of Rectangle object
print(r1.area(r1))

Output

When the above code is built and executed, it produces the following result −

50
50

Example - Using function within same Table

Let's rewrite the above example, to include the function area within Rectangle table.

main.lua

-- create a Rectangle class
Rectangle = {
   length = 10, breadth = 5,

   -- compute area of Rectangle
   area = function (self)
      local area = self.length * self.breadth
	  return area
   end
}

-- create rectangle object
r1 = Rectangle

-- compute and print area of Rectangle object
print(r1.area(r1))

-- create another rectangle object
r2 = Rectangle

-- set new length, keep breadth same
r2.length = 20

-- compute and print area of Rectangle object
print(r2.area(r2))

Output

When the above code is built and executed, it produces the following result −

50
100

Example - Using function without passing same object

Let's rewrite the above example, to use : notation. Lua provides a special notation to access function of an object by passing self as argument internally. So we're not required to pass same object while calling the function.

main.lua

-- create a Rectangle class
Rectangle = {
   length = 10, breadth = 5,

   -- compute area of Rectangle
   area = function (self)
      local area = self.length * self.breadth
	  return area
   end
}

-- create rectangle object
r1 = Rectangle

-- compute and print area of Rectangle object
print(r1:area())

-- create another rectangle object
r2 = Rectangle

-- set new length, keep breadth same
r2.length = 20

-- compute and print area of Rectangle object
print(r2:area())

Output

When the above code is built and executed, it produces the following result −

50
100
Advertisements