Lua - Returning Functions Table from Modules



Returning table of functions from a module is very powerful and effective technique to structure lua codes. We can group related functionalities under a module. It helps making API clearer and organized.

In module, generally we return a table or a single function with mixed data. Now we can specifically design a table where every component is a function. This table will now acts as module's interface. For example, we can create a module which provides string manipulation functions.

Let's define a module file stringutils.lua as described below −

stringutils.lua

local utils = {}

-- function to reverse a string
function utils.reverse(s)
  return s:reverse()
end

-- function to get string in uppercase
function utils.uppercase(s)
  return s:upper()
end

-- function to get string in lowercase
function utils.lowercase(s)
  return s:lower()
end

-- function to check a substring
function utils.contains(s, sub)
  return s:find(sub, 1, true) ~= nil
end

return utils

Now, in order to access factory function from Lua module in another file, say, moduletutorial.lua, you need to use the following code segment.

moduletutorial.lua

-- load the module
stringutils = require("stringutils")

-- reverse a string
local reversed = stringUtils.reverse("hello")
-- prints Reversed: olleh
print("Reversed:", reversed)

-- get uppercase string of passed string
local upperCaseString = stringUtils.uppercase("world")
-- prints Uppercase: WORLD
print("Uppercase:", upperCaseString)

-- get lowercase string of passed string
local lowerCaseString = stringUtils.lowercase("LUA")
-- prints Lowercase: WORLD
print("Lowercase:", lowerCaseString)

-- check if string is present
local contains = stringUtils.contains("programming", "program")
-- prints Contains 'program': true
print("Contains 'program':", contains) 

Output

In order to run this code, we need to place the two Lua files in the same directory or alternatively, you can place the module file in the package path and it needs additional setup. When we run the above program, we will get the following output−

Reversed:       olleh
Uppercase:      WORLD
Lowercase:      lua
Contains 'program':     true

Explanation

stringutils.lua

  • We've created an empty table utils as a module.

  • As next, we've defined various functions like reverse, uppercase, lowercase and contains and assigned them in utils table.

  • In the end, we're returning the utils table.

moduletutorial.lua

  • stringutils = require("stringutils") statement is used to load the module and assign to stringutils variable.

  • As next, we're accessing stringutils module's functions using dot(.) notation and corresponding results are printed.

Advantages of a functions table

Instead of returnin a single function from a module, like a function factory to create specialized functions, it is generally preferred to get a table of functions of related functioanlities. This way we can classify and organize a module in a better way. Following are main advantages of returning functions table from a module −

  • Clear and Concise API − A table of functions provides a clear interface of functionalities of a module. This helps in writing cleaner and easy to understand code.

  • Easy Organization − We can group related functions in modules and name them accordingly so that it is easy to identify related functions.

  • Avoid Collision − We can define functions with same name in different modules. This helps in keeping global scope clean. It also prevents any naming conflicts. We can access a function using module name as we can see in above example as stringUtils.reverse.

  • Extensibility − We can add more related functions to a module by adding new entries to the table.

  • Improved Readablity − A module name like stringutils, math, string and related funtion like math.sin(), math.cos(), string.substring() and stringutils.reverse() improves readabilty of the code as origin of functions is quite helpful and clearly defined.

Advertisements