
- Lua Tutorial
- Lua - Home
- Lua Basics
- Lua - Overview
- Lua - Environment
- Lua - Basic Syntax
- Lua - Comments
- Lua - Print Hello World
- Lua - Variables
- Lua - Data Types
- Lua - Operators
- Lua - Loops
- Lua - Generic For
- Lua - Decision Making
- Lua - Date and Time
- Lua Functions
- Lua - Functions
- Lua - Multiple Results
- Lua - Named Arguments
- Lua - Default/Optional Arguments
- Lua - Closures
- Lua - Uses of Closures
- Lua - Local Functions
- Lua - Anonymous Functions
- Lua - Functions in Table
- Lua - Proper Tail Calls
- Lua Strings
- Lua - Strings
- Lua - String Concatenation
- Lua - Loop Through String
- Lua - String to Int
- Lua - Split String
- Lua - Check String is NULL
- Lua Arrays
- Lua - Arrays
- Lua - Multi-dimensional Arrays
- Lua - Array Length
- Lua - Iterating Over Arrays
- Lua - Slicing Arrays
- Lua - Sorting Arrays
- Lua - Merging Arrays
- Lua - Sparse Arrays
- Lua - Searching Arrays
- Lua - Resizing Arrays
- Lua - Array to String Conversion
- Lua - Array as Stack
- Lua - Array as Queue
- Lua - Array with Metatables
- Lua - Immutable Arrays
- Lua - Shuffling Arrays
- Lua Iterators
- Lua - Iterators
- Lua - Stateless Iterators
- Lua - Stateful Iterators
- Lua - Built-in Iterators
- Lua - Custom Iterators
- Lua - Iterator Closures
- Lua - Infinite Iterators
- Lua - File Iterators
- Lua - Table Iterators
- Lua - Numeric Iterators
- Lua - Reverse Iterators
- Lua - Filter Iterators
- Lua - Range Iterators
- Lua - Chaining Iterators
- Lua Tables
- Lua - Tables
- Lua - Tables as Arrays
- Lua - Tables as Dictionaries
- Lua - Tables as Sets
- Lua - Table Length
- Lua - Table Iteration
- Lua - Table Constructors
- Lua - Loop through Table
- Lua - Merge Tables
- Lua - Nested Tables
- Lua - Accessing Table Fields
- Lua - Copy Table by Value
- Lua - Get Entries from Table
- Lua - Table Metatables
- Lua - Tables as Objects
- Lua - Table Inheritance
- Lua - Table Cloning
- Lua - Table Sorting
- Lua - Table Searching
- Lua - Table Serialization
- Lua - Weak Tables
- Lua - Table Memory Management
- Lua - Tables as Stacks
- Lua - Tables as Queues
- Lua - Sparse Tables
- Lua Lists
- Lua - Lists
- Lua - Inserting Elements into Lists
- Lua - Removing Elements from Lists
- Lua - Iterating Over Lists
- Lua - Reverse Iterating Over Lists
- Lua - Accessing List Elements
- Lua - Modifying List Elements
- Lua - List Length
- Lua - Concatenate Lists
- Lua - Slicing Lists
- Lua - Sorting Lists
- Lua - Reversing Lists
- Lua - Searching in Lists
- Lua - Shuffling List
- Lua - Multi-dimensional Lists
- Lua - Sparse Lists
- Lua - Lists as Stacks
- Lua - Lists as Queues
- Lua - Functional Operations on Lists
- Lua - Immutable Lists
- Lua - List Serialization
- Lua - Metatables with Lists
- Lua Modules
- Lua - Modules
- Lua - Returning Functions from Modules
- Lua - Returning Functions Table from Modules
- Lua - Module Scope
- Lua - SubModule
- Lua - Module Caching
- Lua - Custom Module Loaders
- Lua - Namespaces
- Lua - Singleton Modules
- Lua - Sharing State Between Modules
- Lua - Module Versioning
- Lua Metatables
- Lua - Metatables
- Lua - Chaining Metatables
- Lua Coroutines
- Lua - Coroutines
- Lua File Handling
- Lua - File I/O
- Lua - Opening Files
- Lua - Modes for File Access
- Lua - Reading Files
- Lua - Writing Files
- Lua - Closing Files
- Lua - Renaming Files
- Lua - Deleting Files
- Lua - File Buffers and Flushing
- Lua - Reading Files Line by Line
- Lua - Binary File Handling
- Lua - File Positioning
- Lua - Appending to Files
- Lua - Error Handling in File Operations
- Lua - Checking if File exists
- Lua - Checking if File is Readable
- Lua - Checking if File is Writable
- Lua - Checking if File is ReadOnly
- Lua - File Descriptors
- Lua - Creating Temporary Files
- Lua - Working with Large Files
- Lua Advanced
- Lua - Error Handling
- Lua - Debugging
- Lua - Garbage Collection
- Lua - Object Oriented
- Lua - Web Programming
- Lua - Database Access
- Lua - Game Programing
- Lua Useful Resources
- Lua - Quick Guide
- Lua - Useful Resources
- Lua - Discussion
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.