Lua Tutorial PDF
Lua Tutorial PDF
Lua Tutorial PDF
This tutorial covers various topics ranging from the basics of Lua to its scope in
various applications.
Audience
This tutorial is designed for all those readers who are looking for a starting point
to learn Lua. It has topics suitable for both beginners as well as advanced users.
Prerequisites
It is a self-contained tutorial and you should be able to grasp the concepts easily
even if you are a total beginner. However it would help if you have a basic
understanding of working with a simple text editor and command line.
All the content and graphics published in this e-book are the property of
Tutorials Point (I) Pvt. Ltd. The user of this e-book is prohibited to reuse, retain,
copy, distribute or republish any contents or a part of contents of this e-book in
any manner without written consent of the publisher.
We strive to update the contents of our website and tutorials as timely and as
precisely as possible, however, the contents may contain inaccuracies or errors.
Tutorials Point (I) Pvt. Ltd. provides no guarantee regarding the accuracy,
timeliness or completeness of our website or its contents including this tutorial.
If you discover any errors on our website or in this tutorial, please notify us at
contact@tutorialspoint.com
i
Table of Contents
About the Tutorial ..................................................................................................................................... i
Audience .................................................................................................................................................... i
Prerequisites .............................................................................................................................................. i
1. OVERVIEW ............................................................................................................................ 1
Features .................................................................................................................................................... 1
Learning Lua.............................................................................................................................................. 2
2. ENVIRONMENT ..................................................................................................................... 3
Installation on Linux.................................................................................................................................. 4
Comments ................................................................................................................................................ 9
ii
Identifiers ................................................................................................................................................. 9
Keywords .................................................................................................................................................. 9
4. VARIABLES .......................................................................................................................... 11
6. OPERATORS ........................................................................................................................ 16
7. LOOPS ................................................................................................................................. 25
if statement ............................................................................................................................................ 36
iii
if...else statement ................................................................................................................................... 37
9. FUNCTIONS ......................................................................................................................... 42
Function Arguments................................................................................................................................ 43
Stateful Iterators..................................................................................................................................... 58
iv
13. TABLES ................................................................................................................................ 60
Introduction ............................................................................................................................................ 60
14. MODULES............................................................................................................................ 66
__index ................................................................................................................................................... 70
__newindex ............................................................................................................................................ 71
__call ...................................................................................................................................................... 74
__tostring ............................................................................................................................................... 75
Introduction ............................................................................................................................................ 76
v
17. FILE I/O................................................................................................................................ 81
Introduction to OOP................................................................................................................................ 99
vi
Inheritance in Lua ................................................................................................................................. 102
Xavante................................................................................................................................................. 111
vii
Importing SQLite ................................................................................................................................... 120
viii
27. OPERATING SYSTEM FACILITIES......................................................................................... 138
ix
Lua
1. OVERVIEW
It was designed from the beginning to be a software that can be integrated with
the code written in C and other conventional languages. This integration brings
many benefits. It does not try to do what C can already do but aims at offering
what C is not good at: a good distance from the hardware, dynamic structures,
no redundancies, ease of testing and debugging. For this, Lua has a safe
environment, automatic memory management, and good facilities for handling
strings and other kinds of data with dynamic size.
Features
Lua provides a set of unique features that makes it distinct from other
languages. These include:
Extensible
Simple
Efficient
Portable
Example Code
print("Hello World!")
Both Lua's language and its interpreter are mature, small, and fast. It has
evolved from other programming languages and top software standards. Being
small in size makes it possible for it to run on small devices with low memory.
1
Lua
Learning Lua
The most important point while learning Lua is to focus on the concepts without
getting lost in its technical details.
Scripting in Web
Extensions and add-ons for databases like MySQL Proxy and MySQL
WorkBench
2
Lua
2. ENVIRONMENT
Try the following example using our online compiler option available at
http://www.compileonline.com/
#!/usr/local/bin/lua
print("Hello World!")
For most of the examples given in this tutorial, you will find a Try it option in our
website code sections at the top right corner that will take you to the online
compiler. So, just make use of it and enjoy your learning.
Text Editor
You need a text editor to type your program. Examples of a few editors include
Windows Notepad, OS Edit command, Brief, Epsilon, EMACS, and vim or vi.
Name and version of the text editor can vary on different operating systems. For
example, Notepad will be used on Windows, and vim or vi can be used on
Windows as well as Linux or UNIX.
The files you create with your editor are called source files and these files
contain the program source code. The source files for Lua programs are typically
named with the extension ".lua".
3
Lua
Installation on Windows
There is a separate IDE named "SciTE" developed for the windows environment,
which can be downloaded from
http://code.google.com/p/luaforwindows/ download section.
Since its an IDE, you can both create and build the Lua code using the same.
In case, you are interested in installing Lua in command line mode, you need to
install MinGW or Cygwin and then compile and install Lua in windows.
Installation on Linux
To download and build Lua, use the following command:
$ wget http://www.lua.org/ftp/lua-5.2.3.tar.gz
$ tar zxf lua-5.2.3.tar.gz
$ cd lua-5.2.3
$ make linux test
In order to install on other platforms like aix, ansi, bsd, generic linux, mingw,
posix, solaris by replacing Linux in make Linux, test with the corresponding
platform name.
print("Hello World!")
Now, we can build and run a Lua file say helloWorld.lua, by switching to the
folder containing the file using cd, and then using the following command:
$ lua helloWorld
4
Lua
Installation on Mac OS X
To build/test Lua in the Mac OS X, use the following command:
$ curl -R -O http://www.lua.org/ftp/lua-5.2.3.tar.gz
$ tar zxf lua-5.2.3.tar.gz
$ cd lua-5.2.3
$ make macosx test
In certain cases, you may not have installed the Xcode and command line tools.
In such cases, you wont be able to use the make command. Install Xcode from
mac app store. Then go to Preferences of Xcode, and then switch to Downloads
and install the component named "Command Line Tools". Once the process is
completed, make command will be available to you.
It is not mandatory for you to execute the "make macosx test" statement. Even
without executing this command, you can still use Lua in Mac OS X.
print("Hello World!")
Now, we can build and run a Lua file say helloWorld.lua by switching to the
folder containing the file using cd and then using the following command:
$ lua helloWorld
hello world
Lua IDE
As mentioned earlier, for Windows SciTE, Lua IDE is the default IDE provided by
the Lua creator team. The alternate IDE available is from ZeroBrane
Studio, which is available across multiple platforms like Windows, Mac and Linux.
There are also plugins for eclipse that enable the Lua development. Using IDE
makes it easier for development with features like code completion and is highly
recommended. The IDE also provides interactive mode programming similar to
the command line version of Lua.
5
Lua
6
Lua
3. BASIC SYNTAX
$ lua -i
$ Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
quit to end; cd, dir and edit also available
> print("test")
Once you press enter, you will get the following output:
'test'
Let us write a simple Lua program. All Lua files will have extension .lua. So put
the following source code in a test.lua file.
print("test")
Assuming, lua environment is setup correctly, lets run the program using the
following code:
$ lua test.lua
7
Lua
test
Let's try another way to execute a Lua program. Below is the modified test.lua
file:
#!/usr/local/bin/lua
print("test")
Here, we have assumed that you have Lua interpreter available in your
/usr/local/bin directory. The first line is ignored by the interpreter, if it starts
with # sign. Now, try to run this program as follows:
test
Let us now see the basic structure of Lua program, so that it will be easy for you
to understand the basic building blocks of the Lua programming language.
Tokens in Lua
A Lua program consists of various tokens and a token is either a keyword, an
identifier, a constant, a string literal, or a symbol. For example, the following
Lua statement consists of three tokens:
io.write
(
"Hello world, from ",_VERSION,"!\n"
)
8
Lua
Comments
Comments are like helping text in your Lua program and they are ignored by the
interpreter. They start with --[[ and terminates with the characters --]] as
shown below:
Identifiers
A Lua identifier is a name used to identify a variable, function, or any other
user-defined item. An identifier starts with a letter A to Z or a to z or an
underscore _ followed by zero or more letters, underscores, and digits (0 to 9).
Keywords
The following list shows few of the reserved words in Lua. These reserved words
may not be used as constants or variables or any other identifier names.
function if in local
while
9
Lua
Whitespace in Lua
A line containing only whitespace, possibly with a comment, is known as a blank
line, and a Lua interpreter totally ignores it.
Whitespace is the term used in Lua to describe blanks, tabs, newline characters
and comments. Whitespace separates one part of a statement from another and
enables the interpreter to identify where one element in a statement, such as int
ends, and the next element begins. Therefore, in the following statement:
local age
There must be at least one whitespace character (usually a space) between local
and age for the interpreter to be able to distinguish them. On the other hand, in
the following statement:
10
Lua
4. VARIABLES
A variable is nothing but a name given to a storage area that our programs can
manipulate. It can hold different types of values including functions and tables.
The name of a variable can be composed of letters, digits, and the underscore
character. It must begin with either a letter or an underscore. Upper and
lowercase letters are distinct because Lua is case-sensitive. There are eight basic
types of values in Lua:
In Lua, though we don't have variable data types, we have three types based on
the scope of the variable.
Local variables: When the type is specified as local for a variable then its
scope is limited with the functions inside their scope.
Table fields: This is a special type of variable that can hold anything
except nil including functions.
type variable_list;
local i, j
local i
local a,c
The line local i, j both declares and defines the variables i and j; which instructs
the interpreter to create variables named i, j and limits the scope to be local.
11
Lua
For definition without an initializer: variables with static storage duration are
implicitly initialized with nil.
Value assigning in Lua takes place like first variable in the variable_list with first
value in the value_list and so on. Hence, the value of d is 5 and the value of f is
10.
Example
Try the following example, where variables have been declared at the top, but
they have been defined and initialized inside the main function:
-- Variable definition:
local a, b
-- Initialization
a = 10
b = 30
print("value of a:", a)
print("value of b:", b)
-- Swapping of variables
b, a = a, b
print("value of a:", a)
12
Lua
print("value of b:", b)
f = 70.0/3.0
print("value of f", f)
When the above code is built and executed, it produces the following result:
value of a: 10
value of b: 30
value of a: 30
value of b: 10
value of f 23.333333333333
rvalue: The term rvalue refers to a data value that is stored at some
address in memory. An rvalue is an expression that cannot have a value
assigned to it, which means an rvalue may appear on the right-hand side,
but not on the left-hand side of an assignment.
Variables are lvalues and so may appear on the left-hand side of an assignment.
Numeric literals are rvalues and so may not be assigned and cannot appear on
the left-hand side. Following is a valid statement:
g = 20
But following is not a valid statement and would generate a build-time error:
10 = 20
g,l = 20,30
13
Lua
5. DATA TYPES
Lua is a dynamically typed language, so the variables don't have types, only the
values have types. Values can be stored in variables, passed as parameters and
returned as results.
In Lua, though we don't have variable data types, but we have types for the
values. The list of data types for values are given below.
boolean Includes true and false as values. Generally used for condition
checking.
Type Function
In Lua, there is a function called type that enables us to know the type of the
variable. Some examples are given in the following code.
14
Lua
t=10
print(type(5.8*t)) --> number
When you build and execute the above program, it produces the following result
on Linux:
string
number
function
function
boolean
nil
string
By default, all the variables will point to nil until they are assigned a value or
initialized. In Lua, zero and empty strings are considered to be true in case of
condition checks. Hence, you have to be careful when using Boolean operations.
We will know more using these types in the next chapters.
15
Lua
6. OPERATORS
Arithmetic Operators
Relational Operators
Logical Operators
Misc Operators
This tutorial will explain the arithmetic, relational, logical, and other
miscellaneous operators one by one.
Arithmetic Operators
Following table shows all the arithmetic operators supported by Lua language.
Assume variable A holds 10 and variable B holds 20, then:
Example
16
Lua
Try the following example to understand all the arithmetic operators available in
the Lua programming language:
a = 21
b = 10
c = a + b
print("Line 1 - Value of c is ", c )
c = a - b
print("Line 2 - Value of c is ", c )
c = a * b
print("Line 3 - Value of c is ", c )
c = a / b
print("Line 4 - Value of c is ", c )
c = a % b
print("Line 5 - Value of c is ", c )
c = a^2
print("Line 6 - Value of c is ", c )
c = -a
print("Line 7 - Value of c is ", c )
When you execute the above program, it produces the following result:
Line 1 - Value of c is 31
Line 2 - Value of c is 11
Line 3 - Value of c is 210
Line 4 - Value of c is 2.1
Line 5 - Value of c is 1
Line 6 - Value of c is 441
Line 7 - Value of c is -21
Relational Operators
Following table shows all the relational operators supported by Lua language.
Assume variable A holds 10 and variable B holds 20 then:
17
Lua
Example
Try the following example to understand all the relational operators available in
the Lua programming language:
a = 21
b = 10
if( a == b )
then
print("Line 1 - a is equal to b" )
else
print("Line 1 - a is not equal to b" )
end
18
Lua
if( a ~= b )
then
print("Line 2 - a is not equal to b" )
else
print("Line 2 - a is equal to b" )
end
if ( a < b )
then
print("Line 3 - a is less than b" )
else
print("Line 3 - a is not less than b" )
end
if ( a > b )
then
print("Line 4 - a is greater than b" )
else
print("Line 5 - a is not greater than b" )
end
if ( b >= a )
then
print("Line 6 - b is either greater than or equal to b" )
end
19
Lua
When you build and execute the above program, it produces the following result:
Logical Operators
Following table shows all the logical operators supported by Lua language.
Assume variable A holds true and variable B holds false then:
Example
Try the following example to understand all the logical operators available in the
Lua programming language:
a = 5
b = 20
if ( a and b )
then
print("Line 1 - Condition is true" )
20
Lua
end
if ( a or b )
then
print("Line 2 - Condition is true" )
end
if ( a and b )
then
print("Line 3 - Condition is true" )
else
print("Line 3 - Condition is not true" )
end
if ( not( a and b) )
then
print("Line 4 - Condition is true" )
else
print("Line 3 - Condition is not true" )
end
When you build and execute the above program, it produces the following result:
21
Lua
Misc Operators
Miscellaneous operators supported by Lua Language include concatenation and
length.
Example
Try the following example to understand the miscellaneous operators available in
the Lua programming language:
a = "Hello "
b = "World"
print("Length of b is ",#b )
print("Length of b is ",#"Test" )
When you build and execute the above program, it produces the following result:
22
Lua
Here, operators with the highest precedence appear at the top of the table,
those with the lowest appear at the bottom. Within an expression, higher
precedence operators will be evaluated first.
Example
Try the following example to understand all the precedence of operators in Lua
programming language:
a = 20
b = 10
c = 15
d = 5
e = (a + b) * c / d;-- ( 30 * 15 ) / 5
print("Value of (a + b) * c / d is :",e )
e = ((a + b) * c) / d; -- (30 * 15 ) / 5
23
Lua
e = a + (b * c) / d; -- 20 + (150/5)
print("Value of a + (b * c) / d is :",e )
When you build and execute the above program, it produces the following result:
Value of (a + b) * c / d is : 90
Value of ((a + b) * c) / d is : 90
Value of (a + b) * (c / d) is : 90
Value of a + (b * c) / d is : 50
24
Lua
7. LOOPS
There may be a situation when you need to execute a block of code several
number of times. In general, statements are executed sequentially: the first
statement in a function is executed first, followed by the second, and so on.
Programming languages provide various control structures that allow for more
complicated execution paths.
25
Lua
nested loops You can use one or more loop inside any another
while, for or do..while loop.
while loop
A while loop statement in Lua programming language repeatedly executes a
target statement as long as a given condition is true.
Syntax
The syntax of a while loop in Lua programming language is as follows:
while(condition)
do
statement(s)
end
When the condition becomes false, the program control passes to the line
immediately following the loop.
Flow Diagram
26
Lua
Here, the key point to note is that the while loop might not be executed at all.
When the condition is tested and the result is false, the loop body will be skipped
and the first statement after the while loop will be executed.
Example
a=10
while( a < 20 )
do
print("value of a:", a)
a = a+1
end
When the above code is built and executed, it produces the following result:
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
value of a: 16
value of a: 17
value of a: 18
value of a: 19
for loop
A for loop is a repetition control structure that allows you to efficiently write a
loop that needs to execute a specific number of times.
Syntax
The syntax of a for loop in Lua programming language is as follows:
1. The init step is executed first, and only once. This step allows you to
declare and initialize any loop control variables.
2. Next, the max/min. This is the maximum or minimum value till which the
loop continues to execute. It creates a condition check internally to
compare between the initial value and maximum/minimum value.
3. After the body of the for loop executes, the flow of the control jumps back
up to the increment/decrement statement. This statement allows you
to update any loop control variables.
4. The condition is now evaluated again. If it is true, the loop executes and
the process repeats itself (body of loop, then increment step, and then
again condition). After the condition becomes false, the for loop
terminates.
Flow Diagram
Example
28
Lua
for i=10,1,-1
do
print(i)
end
When the above code is built and executed, it produces the following result:
10
9
8
7
6
5
4
3
2
1
repeat...until loop
Unlike the for and while loops, which test the loop condition at the top of the
loop, the repeat...until loop in Lua programming language checks its condition
at the bottom of the loop.
Syntax
The syntax of a repeat...until loop in Lua programming language is as follows:
repeat
statement(s)
while( condition )
Notice that the conditional expression appears at the end of the loop, so the
statement(s) in the loop execute(s) once before the condition is tested.
If the condition is false, the flow of control jumps back up to do, and the
statement(s) in the loop execute again. This process repeats until the given
condition becomes true.
29
Lua
Flow Diagram
Example
--[ local variable definition --]
a = 10
--[ repeat loop execution --]
repeat
print("value of a:", a)
a = a + 1
until( a > 15 )
When you build and execute the above program, it produces the following result:
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
30
Lua
nested loops
Lua programming language allows to use one loop inside another loop. Following
section shows few examples to illustrate the concept.
Syntax
The syntax for a nested for loop statement in Lua is as follows:
The syntax for a nested while loop statement in Lua programming language is
as follows:
while(condition)
do
while(condition)
do
statement(s)
end
statement(s)
end
repeat
statement(s)
repeat
statement(s)
until( condition )
until( condition )
31
Lua
A final note on loop nesting is that you can put any type of loop inside of any
other type of loop. For example, a for loop can be inside a while loop or vice
versa.
Example
The following program uses a nested for loop:
j =2
for i=2,10 do
for j=2,(i/j) , 2 do
if(not(i%j))
then
break
end
if(j > (i/j))then
print("Value of i is",i)
end
end
end
When you build and run the above code, it produces the following result.
Value of i is 8
Value of i is 9
Value of i is 10
32
Lua
break statement
When the break statement is encountered inside a loop, the loop is immediately
terminated and the program control resumes at the next statement following the
loop.
If you are using nested loops (i.e., one loop inside another loop), the break
statement will stop execution of the innermost loop and start executing the next
line of code after the block.
Syntax
The syntax for a break statement in Lua is as follows:
break
Flow Diagram
Example
33
Lua
print("value of a:", a)
a=a+1
if( a > 15)
then
--[ terminate the loop using break statement --]
break
end
end
When you build and run the above code, it produces the following result.
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
while( true )
do
print("This loop will run forever.")
end
34
Lua
8. DECISION MAKING
Decision making structures require that the programmer specifies one or more
conditions to be evaluated or tested by the program, along with a statement or
statements to be executed, if the condition is determined to be true, and
optionally, other statements to be executed if the condition is determined to be
false.
Lua programming language assumes any combination of Boolean true and non-
nil values as true, and if it is either Boolean false or nil, then it is assumed
as false value. It is to be noted that in Lua, zero will be considered as true.
Statement Description
35
Lua
expression is false.
if statement
An if statement consists of a Boolean expression followed by one or more
statements.
Syntax
The syntax of an if statement in Lua programming language is:
if(boolean_expression)
then
--[ statement(s) will execute if the boolean expression is true --]
end
If the Boolean expression evaluates to true, then the block of code inside the if
statement will be executed. If Boolean expression evaluates to false, then the
first set of code after the end of the if statement (after the closing curly brace)
will be executed.
Lua programming language assumes any combination of Boolean true and non-
nil values as true, and if it is either Boolean false or nil, then it is assumed
as false value. It is to be noted that in Lua, zero will be considered as true.
Flow Diagram
36
Lua
Example
When you build and run the above code, it produces the following result.
a is less than 20
value of a is : 10
if...else statement
An if statement can be followed by an optional else statement, which executes
when the Boolean expression is false.
Syntax
The syntax of an if...else statement in Lua programming language is:
if(boolean_expression)
then
--[ statement(s) will execute if the boolean expression is true --]
else
--[ statement(s) will execute if the boolean expression is false --]
end
If the Boolean expression evaluates to true, then the if block of code will be
executed, otherwise else block of code will be executed.
Lua programming language assumes any combination of Boolean true and non-
nil values as true, and if it is either Boolean false or nil, then it is assumed
as false value. It is to be noted that in Lua, zero will be considered as true.
37
Lua
Flow Diagram
Example
When you build and run the above code, it produces the following result.
38
Lua
While using if, else if, else statements, there are a few points to keep in mind:
An if can have zero or one else's and it must come after any else if's.
An if can have zero to many else if's and they must come before the else.
Once an else if succeeds, none of the remaining else if's or else's will be tested.
Syntax
The syntax of an if...else if...else statement in Lua programming language is:
if(boolean_expression 1)
then
--[ Executes when the boolean expression 1 is true --]
Example
then
--[ if else if condition is true --]
print("Value of a is 20" )
elseif( a == 30 )
then
--[ if else if condition is true --]
print("Value of a is 30" )
else
--[ if none of the conditions is true --]
print("None of the values is matching" )
end
print("Exact value of a is: ", a )
When you build and run the above code, it produces the following result.
nested if statements
It is always legal in Lua programming to nest if-else statements, which means
you can use one if or else if statement inside another if or else if statement(s).
Syntax
The syntax for a nested if statement is as follows:
if( boolean_expression 1)
then
--[ Executes when the boolean expression 1 is true --]
if(boolean_expression 2)
then
--[ Executes when the boolean expression 2 is true --]
end
end
You can nest else if...else in the similar way as you have nested if statement.
40
Lua
Example
When you build and run the above code, it produces the following result.
41
Lua
9. FUNCTIONS
A function is a group of statements that together perform a task. You can divide
up your code into separate functions. How you divide up your code among
different functions is up to you, but logically the division usually is unique, so
each function performs a specific task.
The Lua language provides numerous built-in methods that your program can
call. For example, method print() to print the argument passed as input in
console.
Defining a Function
The general form of a method definition in Lua programming language is as
follows:
Optional Function Scope: You can use keyword local to limit the scope
of the function or ignore the scope section, which will make it a global
function.
Function Name: This is the actual name of the function. The function
name and the parameter list together constitute the function signature.
42
Lua
Example
Following is the source code for a function called max(). This function takes two
parameters num1 and num2 and returns the maximum between the two:
return result;
end
Function Arguments
If a function is to use arguments, it must declare the variables that accept the
values of the arguments. These variables are called the formal parameters of
the function.
The formal parameters behave like other local variables inside the function and
are created upon entry into the function and destroyed upon exit.
Calling a Function
While creating a Lua function, you give a definition of what the function has to
do. To use a method, you will have to call that function to perform the defined
task.
To call a method, you simply need to pass the required parameters along with
the method name and if the method returns a value, then you can store the
returned value. For example:
43
Lua
return result;
end
-- calling a function
print("The maximum of the two numbers is ",max(10,4))
print("The maximum of the two numbers is ",max(5,6))
When we run the above code, we will get the following output.
myprint = function(param)
print("This is my print function - ##",param,"##")
end
function add(num1,num2,functionPrint)
result = num1 + num2
functionPrint(result)
end
myprint(10)
add(2,5,myprint)
44
Lua
When we run the above code, we will get the following output.
function average(...)
result = 0
local arg={...}
for i,v in ipairs(arg) do
result = result + v
end
return result/#arg
end
When we run the above code, we will get the following output.
45
Lua
10. STRINGS
string1 = "Lua"
print("\"String 1 is\"",string1)
string2 = 'Tutorial'
print("String 2 is",string2)
When we run the above program, we will get the following output.
\a Bell
\b Backspace
\f Formfeed
46
Lua
\n New line
\r Carriage return
\t Tab
\v Vertical tab
\\ Backslash
String Manipulation
Lua supports string to manipulate strings:
1 string.upper(argument):
Returns a capitalized representation of the argument.
2 string.lower(argument):
Returns a lower case representation of the argument.
3 string.gsub(mainString,findString,replaceString)
Returns a string by replacing occurrences of findString with
replaceString.
4 string.strfind(mainString,findString,optionalStartIndex,option
alEndIndex)
Returns the start index and end index of the findString in the main
string and nil if not found.
47
Lua
5 string.reverse(arg)
Returns a string by reversing the characters of the passed string.
6 string.format(...)
Returns a formatted string.
8 string.len(arg)
Returns a length of the passed string.
9 string.rep(string, n))
Returns a string by repeating the same string n number times.
10 ..
Thus operator concatenates two strings.
Now, lets dive into a few examples to exactly see how these string manipulation
functions behave.
Case Manipulation
A sample code for manipulating the strings to upper and lower case is given
below.
string1 = "Lua";
print(string.upper(string1))
print(string.lower(string1))
When we run the above program, we will get the following output.
LUA
lua
Replacing a Substring
A sample code for replacing occurrences of one string with another is given
below.
48
Lua
newstring = string.gsub(string,"Tutorial","Language")
print("The new string is",newstring)
When we run the above program, we will get the following output.
When we run the above program, we will get the following output.
5 12
The new string is lairotuT auL
Formatting Strings
Many times in our programming, we may need to print strings in a formatted
way. You can use the string.format function to format the output as shown
below.
string1 = "Lua"
string2 = "Tutorial"
number1 = 10
number2 = 20
-- Basic string formatting
print(string.format("Basic formatting %s %s",string1,string2))
-- Date formatting
49
Lua
-- Decimal formatting
print(string.format("%.4f",1/3))
When we run the above program, we will get the following output.
-- Byte conversion
-- First character
print(string.byte("Lua"))
-- Third character
print(string.byte("Lua",3))
-- first character from last
print(string.byte("Lua",-1))
-- Second character
print(string.byte("Lua",2))
-- Second character from last
print(string.byte("Lua",-2))
When we run the above program, we will get the following output.
76
97
97
50
Lua
117
117
string1 = "Lua"
string2 = "Tutorial"
-- String Concatenations using ..
print("Concatenated string",string1..string2)
-- Length of string
print("Length of string1 is ",string.len(string1))
-- Repeating strings
repeatedString = string.rep(string1,3)
print(repeatedString)
When we run the above program, we will get the following output.
51
Lua
11. ARRAYS
In Lua, arrays are implemented using indexing tables with integers. The size of
an array is not fixed and it can grow based on our requirements, subject to
memory constraints.
One-Dimensional Array
A one-dimensional array can be represented using a simple table structure and
can be initialized and read using a simple for loop. An example is shown below.
for i= 0, 2 do
print(array[i])
end
When we run the above code, we will get the following output.
nil
Lua
Tutorial
As you can see in the above code, when we are trying to access an element in
an index that is not there in the array, it returns nil. In Lua, indexing generally
starts at index 1. But it is possible to create objects at index 0 and below 0 as
well. Array using negative indices is shown below where we initialize the array
using a for loop.
array = {}
for i= -2, 2 do
array[i] = i *2
end
52
Lua
for i = -2,2 do
print(array[i])
end
When we run the above code, we will get the following output.
-4
-2
0
2
4
Multi-Dimensional Array
Multi-dimensional arrays can be implemented in two ways:
Array of arrays
53
Lua
When we run the above code, we will get the following output.
1
2
3
2
4
6
3
6
9
When we run the above code, we will get the following output.
1
2
3
54
Lua
2
4
6
3
6
9
As you can see in the above example, data is stored based on indices. It is
possible to place the elements in a sparse way and it is the way Lua
implementation of a matrix works. Since it does not store nil values in Lua, it is
possible to save lots of memory without any special technique in Lua as
compared to special techniques used in other programming languages.
55
Lua
12. ITERATORS
Iterator is a construct that enables you to traverse through the elements of the
so called collection or container. In Lua, these collections often refer to tables,
which are used to create various data structures like array.
When we run the above code, we will get the following output:
1 Lua
2 Tutorial
The above example uses the default ipairs iterator function provided by Lua.
Stateless Iterators
Stateful Iterators
Stateless Iterators
By the name itself we can understand that this type of iterator function does not
retain any state.
Let us now see an example of creating our own iterator using a simple function
that prints the squares of n numbers.
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
56
Lua
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
When we run the above program, we will get the following output.
1 1
2 4
3 9
The above code can be modified slightly to mimic the way ipairs function of
iterators work. It is shown below.
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
function squares(iteratorMaxCount)
return square,iteratorMaxCount,0
end
57
Lua
When we run the above program, we will get the following output.
1 1
2 4
3 9
Stateful Iterators
The previous example of iteration using function does not retain the state. Each
time the function is called, it returns the next element of the collection based on
a second variable sent to the function. To hold the state of the current element,
closures are used. Closure retain variables values across functions calls. To
create a new closure, we create two functions including the closure itself and a
factory, the function that creates the closure.
Let us now see an example of creating our own iterator in which we will be using
closures.
58
Lua
When we run the above program, we will get the following output.
Lua
Tutorial
In the above example, we can see that elementIterator has another method
inside that uses the local external variables index and count to return each of
the element in the collection by incrementing the index each time the function is
called.
We can create our own function iterators using closure as shown above and it
can return multiple elements for each of the time we iterate through the
collection.
59
Lua
13. TABLES
Introduction
Tables are the only data structure available in Lua that helps us create different
types like arrays and dictionaries. Lua uses associative arrays and which can be
indexed with not only numbers but also with strings except nil. Tables have no
fixed size and can grow based on our need.
--removing reference
mytable = nil
-- lua garbage collection will take care of releasing memory
When we have a table a with set of elements and if we assign it to b, both a and
b refer to the same memory. No separate memory is allocated separately for b.
When a is set to nil, table will be still accessible to b. When there are no
reference to a table, then garbage collection in Lua takes care of cleaning up
process to make these unreferenced memory to be reused again.
60
Lua
mytable = {}
print("Type of mytable is ",type(mytable))
mytable[1]= "Lua"
mytable["wow"] = "Tutorial"
print("mytable Element at index 1 is ", mytable[1])
print("mytable Element at index wow is ", mytable["wow"])
mytable = nil
print("mytable is ", mytable)
When we run the above program we will get the following output:
61
Lua
alternatetable is nil
mytable Element at index wow is I changed it
mytable is nil
Table Manipulation
There are in built functions for table manipulation and they are listed in the
following table.
3 table.maxn (table)
Table Concatenation
We can use the concat function to concatenate two tables as shown below:
fruits = {"banana","orange","apple"}
-- returns concatenated string of table
62
Lua
When we run the above program we will get the following output:
fruits = {"banana","orange","apple"}
63
Lua
When we run the above program, we will get the following output:
Sorting Tables
We often require to sort a table in a particular order. The sort functions sort the
elements in a table alphabetically. A sample for this is shown below.
fruits = {"banana","orange","apple","grapes"}
for k,v in ipairs(fruits) do
print(k,v)
end
table.sort(fruits)
print("sorted table")
for k,v in ipairs(fruits) do
print(k,v)
end
When we run the above program, we will get the following output:
1 banana
2 orange
3 apple
4 grapes
sorted table
1 apple
2 banana
3 grapes
4 orange
64
Lua
65
Lua
14. MODULES
What is a Module?
Module is like a library that can be loaded using require and has a single global
name containing a table. This module can consist of a number of functions and
variables. All these functions and variables are wrapped in to the table, which
acts as a namespace. Also, a well behaved module has necessary provisions to
return this table on require.
-- Method 2
local formatter = require "printFormatter"
formatter.simpleFormat("test")
-- Method 3
require "printFormatter"
local formatterFunction = printFormatter.simpleFormat
formatterFunction("test")
In the above sample code, you can see how flexible programming in Lua is,
without any special additional code.
66
Lua
Example
Let us consider a simple example, where one function has the math functions.
Lets call this module as mymath and filename being mymath.lua. The file
content is as follows:
local mymath = {}
function mymath.add(a,b)
print(a+b)
end
function mymath.sub(a,b)
print(a-b)
end
function mymath.mul(a,b)
print(a*b)
end
function mymath.div(a,b)
print(a/b)
end
return mymath
Now, in order to access this Lua module in another file, say, moduletutorial.lua,
you need to use the following code segment.
mymathmodule = require("mymath")
mymathmodule.add(10,20)
mymathmodule.sub(30,20)
mymathmodule.mul(10,20)
67
Lua
mymathmodule.div(30,20)
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.
30
10
200
1.5
Things to Remember
Place both the modules and the file you run in the same directory.
It is a best practice to return modules for require function and hence the
module should be preferably implemented as shown above even though
you can find other types of implementations elsewhere.
module("mymath", package.seeall)
function mymath.add(a,b)
print(a+b)
end
function mymath.sub(a,b)
print(a-b)
end
function mymath.mul(a,b)
print(a*b)
68
Lua
end
function mymath.div(a,b)
print(a/b)
end
require("mymath")
mymath.add(10,20)
mymath.sub(30,20)
mymath.mul(10,20)
mymath.div(30,20)
When we run the above, we will get the same output. But it is advised on to use
the older version of the code and it is assumed to less secure. Many SDKs that
use Lua for programming like Corona SDK has deprecated the use of this.
69
Lua
15. METATABLES
Looking up metatables when the key is not available in the table using
__index in metatable.
There are two important methods that are used in handling metatables, which
includes -
Lets first look at how to set one table as metatable of another. It is shown
below.
mytable = {}
mymetatable = {}
setmetatable(mytable,mymetatable)
mytable = setmetatable({},{})
__index
A simple example of metatable for looking up the meta table when it's not
available in table is shown below.
70
Lua
end
})
print(mytable.key1,mytable.key2)
When we run the above program, we will get the following output.
value1 metatablevalue
Metatable is set for mytable that contains a function for __index, which
we call as a metamethod.
__newindex
When we add __newindex to metatable, if keys are not available in the table,
the behavior of new keys will be defined by meta methods. A simple example
where metatable's index is set when index is not available in the main table is
given below.
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })
print(mytable.key1)
71
Lua
When you run the above program, you get the following output.
value1
nil new value 2
new value 1 nil
You can see in the above program, if a key exists in the main table, it just
updates it. When a key is not available in the maintable, it adds that key to the
metatable.
Another example that updates the same table using rawset function is shown
below.
end
})
print(mytable.key1,mytable.key2)
When we run the above program we will get the following output.
mytable = setmetatable({ 1, 2, 3 }, {
__add = function(mytable, newtable)
72
Lua
for i = 1, table.maxn(newtable) do
table.insert(mytable, table.maxn(mytable)+1,newtable[i])
end
return mytable
end
})
secondtable = {4,5,6}
When we run the above program, we will get the following output
1 1
2 2
3 3
4 4
5 5
6 6
The __add key is included in the metatable to add behavior of operator +. The
table of keys and corresponding operator is shown below.
Mode Description
73
Lua
__call
Adding behavior of method call is done using __call statement. A simple
example that returns the sum of values in main table with the passed table.
mytable = setmetatable({10}, {
__call = function(mytable, newtable)
sum = 0
for i = 1, table.maxn(mytable) do
sum = sum + mytable[i]
end
for i = 1, table.maxn(newtable) do
sum = sum + newtable[i]
end
return sum
end
})
newtable = {10,20,30}
print(mytable(newtable))
When we run the above program, we will get the following output.
70
74
Lua
__tostring
To change the behavior of the print statement, we can use the __tostring
metamethod. A simple example is shown below.
When we run the above program, we will get the following output.
If you know the capabilities of meta table fully, you can really perform a lot of
operations that would be very complex without using it. So, try to work more on
using metatables with different options available in meta tables as explained in
the samples and also create your own samples.
75
Lua
16. COROUTINES
Introduction
Coroutines are collaborative in nature, which allows two or more methods to
execute in a controlled manner. With coroutines, at any given time, only one
coroutine runs and this running coroutine only suspends its execution when it
explicitly requests to be suspended.
The above definition may look vague. Let us assume we have two methods, one
the main program method and a coroutine. When we call a coroutine using
resume function, its starts executing and when we call yield function, it
suspends executing. Again the same coroutine can continue executing with
another resume function call from where it was suspended. This process can
continue till the end of execution of the coroutine.
1. coroutine.create (f):
3. coroutine.running ():
4. coroutine.status (co):
76
Lua
5. coroutine.wrap (f):
6. coroutine.yield (...):
Example
Let's look at an example to understand the concept of coroutines.
co = coroutine.create(function (value1,value2)
local tempvar3 =10
print("coroutine section 1", value1, value2, tempvar3)
local tempvar1 = coroutine.yield(value1+1,value2+1)
tempvar3 = tempvar3 + value1
print("coroutine section 2",tempvar1 ,tempvar2, tempvar3)
local tempvar1, tempvar2= coroutine.yield(value1+value2, value1-value2)
tempvar3 = tempvar3 + value1
print("coroutine section 3",tempvar1,tempvar2, tempvar3)
return value2, "end"
end)
When we run the above program, we will get the following output.
coroutine section 1 3 2 10
main true 4 3
coroutine section 2 12 nil 13
main true 5 1
coroutine section 3 5 6 16
77
Lua
First, we create a coroutine and assign it to a variable name co, and the
coroutine takes in two variables as its parameters.
When we call the first resume function, the values 3 and 2 are retained in
the temporary variables value1 and value2 till the end of the coroutine.
Another thing about coroutines is how the next params of resume callis
taken care of, in the above example; you can see that the variable the
coroutine.yield receives the next call params, which provides a powerful
way of doing new operation with the retentionship of existing param
values.
Finally, once all the statements in the coroutines are executed, the
subsequent calls will return in false and "cannot resume dead coroutine"
statement as response.
function getNumber()
local function getNumberHelper()
co = coroutine.create(function ()
coroutine.yield(1)
coroutine.yield(2)
78
Lua
coroutine.yield(3)
coroutine.yield(4)
coroutine.yield(5)
end)
return co
end
if(numberHelper) then
status, number = coroutine.resume(numberHelper);
if coroutine.status(numberHelper) == "dead" then
numberHelper = getNumberHelper()
status, number = coroutine.resume(numberHelper);
end
return number
else
numberHelper = getNumberHelper()
status, number = coroutine.resume(numberHelper);
return number
end
end
for index = 1, 10 do
print(index, getNumber())
end
When we run the above program, we will get the following output.
1 1
2 2
3 3
4 4
5 5
6 1
7 2
8 3
9 4
79
Lua
10 5
We control the program execution sequence to meet the needs with the
provision of retaining certain information temporarily. Using global variables with
coroutines provides even more flexibility to coroutines.
80
Lua
I/O library is used for reading and manipulating files in Lua. There are two kinds
of file operations in Lua namely implicit file descriptors and explicit file
descriptors.
For the following examples, we will use a sample file test.lua as shown below.
-- sample test.lua
-- sample2 test.lua
Mode Description
"r" Read-only mode and is the default mode where an existing file
is opened.
"w" Write enabled mode that overwrites the existing file or creates
a new file.
"a" Append mode that opens an existing file or creates a new file
for appending.
"w+" All existing data is removed if file exists or new file is created
with read write permissions.
"a+" Append mode with read mode enabled that opens an existing
file or creates a new file.
81
Lua
When you run the program, you will get an output of the first line of test.lua file.
For our program, we got the following output:
-- Sample test.lua
This was the first line of the statement in test.lua file for us. Also the line "-- End
of the test.lua file" would be appended to the last line of the test.lua code.
82
Lua
In the above example, you can see how the implicit descriptors work with file
system using the io."x" methods. The above example uses io.read() without the
optional parameter. The optional parameter can be any of the following.
Mode Description
"*n" Reads from the current file position and returns a number if
exists at the file position or returns nil.
"*a" Returns all the contents of file from the current file position.
"*l" Reads the line from the current file position, and moves file
position to next line.
io.tmpfile(): Returns a temporary file for reading and writing that will be
removed once the program quits.
io.type(file): Returns whether file, closed file or nil based on the input
file.
83
Lua
When you run the program, you will get a similar output as the implicit
descriptors example.
-- Sample test.lua
All the modes of file open and params for read for external descriptors is same
as implicit file descriptors.
An example to use the seek method is shown below. It offsets the cursor from
the 25 positions prior to the end of file. The read function prints remainder of
the file from seek position.
84
Lua
file:seek("end",-25)
print(file:read("*a"))
sample2 test.lua
--test
You can play around all the different modes and parameters to know the full
ability of the Lua file operations.
85
Lua
Syntax errors
Syntax Errors
Syntax errors occur due to improper use of various program components like
operators and expressions. A simple example for syntax error is shown below.
a == 2
As you know, there is a difference between the use of a single "equal to" and
double "equal to". Using one instead of the other can lead to an error. One
"equal to" refers to assignment while a double "equal to" refers to comparison.
Similarly, we have expressions and functions having their predefined ways of
implementation.
for a= 1,10
print(a)
end
When we run the above program, we will get the following output:
Syntax errors are much easier to handle than run time errors since, the Lua
interpreter locates the error more clearly than in case of runtime error. From the
above error, we can know easily that adding a do statement before print
statement is required as per the Lua structure.
86
Lua
function add(a,b)
return a+b
end
add(10)
When we build the program, it will build successfully and run. Once it runs, it
shows a runtime error.
This is a runtime error, which had occurred due to not passing two variables.
The b parameter is expected and here it is nil and produces an error.
When we run the above program, we will get the following error output.
87
Lua
The error (message [, level]) terminates the last protected function called and
returns message as the error message. This function error never returns.
Usually, error adds some information about the error position at the beginning of
the message. The level argument specifies how to get the error position. With
level 1 (the default), the error position is where the error function was called.
Level 2 points the error to where the function that called error was called; and
so on. Passing a level 0 avoids the addition of error position information to the
message.
The pcall (f, arg1, ...) function calls the requested function in protected mode.
If some error occurs in function f, it does not throw an error. It just returns the
status of error. A simple example using pcall is shown below.
function myfunction ()
n = n/nil
end
if pcall(myfunction) then
print("Success")
else
print("Failure")
end
When we run the above program, we will get the following output.
Failure
The xpcall (f, err) function calls the requested function and also sets the error
handler. Any error inside f is not propagated; instead, xpcall catches the error,
calls the err function with the original error object, and returns a status code.
88
Lua
function myfunction ()
n = n/nil
end
When we run the above program, we will get the following output.
89
Lua
19. DEBUGGING
Lua provides a debug library, which provides all the primitive functions for us to
create our own debugger. Even though, there is no in-built Lua debugger, we
have many debuggers for Lua, created by various developers with many being
open source.
The functions available in the Lua debug library are listed in the following table
along with its uses.
1. debug():
Enters interactive mode for debugging, which remains active till we type
in only cont in a line and press enter. User can inspect variables during
this mode using other functions.
2. getfenv(object):
3. gethook(optional thread):
Returns the current hook settings of the thread, as three values: the
current hook function, the current hook mask, and the current hook
count.
Returns a table with info about a function. You can give the function
directly, or you can give a number as the value of function, which
means the function running at level function of the call stack of the
given thread: level 0 is the current function (getinfo itself); level 1 is
the function that called getinfo; and so on. If function is a number
larger than the number of active functions, then getinfo returns nil.
Returns the name and the value of the local variable with index local of
the function at level of the stack. Returns nil if there is no local variable
with the given index, and raises an error when called with a level out of
range.
90
Lua
6. getmetatable(value):
Returns the metatable of the given object or nil if it does not have a
metatable.
7. getregistry():
Returns the registry table, a pre-defined table that can be used by any
C code to store whatever Lua value it needs to store.
This function returns the name and the value of the upvalue with index
up of the function func. The function returns nil if there is no upvalue
with the given index.
Sets the environment of the given object to the given table. Returns
object.
Sets the given function as a hook. The string mask and the number
count describes when the hook will be called. Here, c, r and l are called
every time Lua calls, returns, and enters every line of code in a function
respectively.
Assigns the value to the local variable with index local of the function at
level of the stack. The function returns nil if there is no local variable
with the given index, and raises an error when called with a level out of
range. Otherwise, it returns the name of the local variable.
Sets the metatable for the given object to the given table (which can be
nil).
This function assigns the value to the upvalue with index up of the
function func. The function returns nil if there is no upvalue with the
91
Lua
The above list is the complete list of debug functions in Lua and we often use a
library that uses the above functions and provides easier debugging. Using these
functions and creating our own debugger is quite complicated and is not
preferable. Anyway, we will see an example of simple use of debugging
functions.
function myfunction ()
print(debug.traceback("Stack trace"))
print(debug.getinfo(1))
print("Stack trace end")
return 10
end
myfunction ()
print(debug.getinfo(1))
When we run the above program, we will get the stack trace as shown below.
Stack trace
stack traceback:
test2.lua:2: in function 'myfunction'
test2.lua:8: in main chunk
[C]: ?
table: 0054C6C8
Stack trace end
In the above sample program, the stack trace is printed by using the
debug.trace function available in the debug library. The debug.getinfo gets the
current table of the function.
92
Lua
Debugging Example
We often need to know the local variables of a function for debugging. For that
purpose, we can use getupvalue and to set these local variables, we use
setupvalue. A simple example for this is shown below.
function newCounter ()
local n = 0
local k = 0
return function ()
k = n
n = n + 1
return n
end
end
counter = newCounter ()
print(counter())
print(counter())
local i = 1
repeat
name, val = debug.getupvalue(counter, i)
if name then
print ("index", i, name, "=", val)
if(name == "n") then
debug.setupvalue (counter,2,10)
end
i = i + 1
end -- if
until not name
print(counter())
93
Lua
When we run the above program, we will get the following output:
1
2
index 1 k = 1
index 2 n = 2
11
In this example, the counter updates by one, each time it is called. We can see
the current state of the local variable using the getupvalue function. We then set
the local variable to a new value. Here, n is 2 before the set operation is called.
Using setupvalue function, it is updated to 10. Now, when we call the counter
function, it will return 11 instead of 3.
Debugging Types
Command line debugging
Graphical debugging
RemDebug: RemDebug is a remote debugger for Lua 5.0 and 5.1. It lets
you control the execution of another Lua program remotely, setting
breakpoints and inspecting the current state of the program. RemDebug
can also debug CGILua scripts.
xdbLua: A simple Lua command line debugger for the Windows platform.
94
Lua
Graphical Debugging
Graphical debugging is available with the help of IDE where you are provided
with visual debugging of various states like variable values, stack trace and
other related information. There is a visual representation and step by step
control of execution with the help of breakpoints, step into, step over and other
buttons in the IDE.
There are number of graphical debuggers for Lua and it includes the following.
SciTE: The default windows IDE for Lua provides multiple debugging
facilities like breakpoints, step, step into, step over, watch variables and
so on.
95
Lua
Lua uses automatic memory management that uses garbage collection based on
certain algorithms that is in-built in Lua. As a result of automatic memory
management, as a developer -
No need to free them when no longer needed except for setting it to nil.
Lua uses a garbage collector that runs from time to time to collect dead objects
when they are no longer accessible from the Lua program.
All objects including tables, userdata, functions, thread, string and so on are
subject to automatic memory management. Lua uses incremental mark and
sweep collector that uses two numbers to control its garbage collection cycles
namely garbage collector pause and garbage collector step multiplier.
These values are in percentage and value of 100 is often equal to 1 internally.
96
Lua
print(collectgarbage("count"))
mytable = nil
print(collectgarbage("count"))
print(collectgarbage("collect"))
print(collectgarbage("count"))
When we run the above program, we will get the following output. Please note
that this result will vary due to the difference in type of operating system and
also the automatic memory management feature of Lua.
20.9560546875
20.9853515625
0
97
Lua
19.4111328125
You can see in the above program, once garbage collection is done, it reduced
the memory used. But, it's not mandatory to call this. Even if we don't call them,
it will be executed automatically at a later stage by Lua interpreter after the
predefined period.
Obviously, we can change the behavior of the garbage collector using these
functions if required. These functions provide a bit of additional capability for the
developer to handle complex situations. Depending on the type of memory need
for the program, you may or may not use this feature. But it is very useful to
know the memory usage in the applications and check it during the
programming itself to avoid undesired results after deployment.
98
Lua
Introduction to OOP
Object Oriented Programming (OOP), is one the most used programming
technique that is used in the modern era of programming. There are a number
of programming languages that support OOP which include,
C++
Java
Objective-C
Smalltalk
C#
Ruby
Features of OOP
Class: A class is an extensible template for creating objects, providing
initial values for state (member variables) and implementations of
behavior.
OOP in Lua
You can implement object orientation in Lua with the help of tables and first
class functions of Lua. By placing functions and related data into a table, an
object is formed. Inheritance can be implemented with the help of metatables,
providing a look up mechanism for nonexistent functions(methods) and fields in
parent object(s).
Tables in Lua have the features of object like state and identity that is
independent of its values. Two objects (tables) with the same value are different
objects, whereas an object can have different values at different times, but it is
99
Lua
always the same object. Like objects, tables have a life cycle that is independent
of who created them or where they were created.
The shapes can have a common property Area. So, we can extend other shapes
from the base object shape with the common property area. Each of the shapes
can have its own properties and functions like a rectangle can have properties
length, breadth, area as its properties and printArea and calculateArea as its
functions.
-- Meta class
Rectangle = {area = 0, length = 0, breadth = 0}
100
Lua
end
Creating an Object
Creating an object is the process of allocating memory for the class instance.
Each of the objects has its own memory and share the common class data.
r = Rectangle:new(nil,10,20)
Accessing Properties
We can access the properties in the class using the dot operator as shown
below:
print(r.length)
r:printArea()
The memory gets allocated and the initial values are set. The initialization
process can be compared to constructors in other object oriented languages. It
is nothing but a function that enables setting values as shown above.
Complete Example
Lets look at a complete example using object orientation in Lua.
-- Meta class
Shape = {area = 0}
101
Lua
self.area = side*side;
return o
end
-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()
When you run the above program, you will get the following output.
Inheritance in Lua
Inheritance is the process of extending simple base objects like shape to
rectangles, squares and so on. It is often used in the real world to share and
extend the basic properties and functions.
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
o = o or {}
setmetatable(o, self)
self.__index = self
side = side or 0
self.area = side*side;
return o
end
102
Lua
Square = Shape:new()
-- Derived class method new
function Square:new (o,side)
o = o or Shape:new(o,side)
setmetatable(o, self)
self.__index = self
return o
end
-- Meta class
Shape = {area = 0}
-- Base class method new
function Shape:new (o,side)
o = o or {}
setmetatable(o, self)
103
Lua
self.__index = self
side = side or 0
self.area = side*side;
return o
end
-- Base class method printArea
function Shape:printArea ()
print("The area is ",self.area)
end
-- Creating an object
myshape = Shape:new(nil,10)
myshape:printArea()
Square = Shape:new()
-- Derived class method new
function Square:new (o,side)
o = o or Shape:new(o,side)
setmetatable(o, self)
self.__index = self
return o
end
-- Creating an object
mysquare = Square:new(nil,10)
mysquare:printArea()
Rectangle = Shape:new()
104
Lua
-- Creating an object
myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()
When we run the above program, we will get the following output:
In the above example, we have created two derived classes - Rectangle and
Square from the base class Square. It is possible to override the functions of the
base class in derived class. In this example, the derived class overrides the
function printArea.
105
Lua
Even though, there are other web frameworks using Lua that have been
developed, we will be primarily focusing on the components provided by Kepler
community.
WSAPI is the API that abstracts the web host server from Lua web
applications and is the base for many projects.
In this tutorial, we will try to make you understand what Lua can do and to know
more about its installation and usage, refer the Kepler website.
Orbit
Orbit is an MVC web framework for Lua. It completely abandons the CGILua
model of "scripts" in favor of applications, where each Orbit application can fit in
a single file, but you can split it into multiple files if you want.
All Orbit applications follow the WSAPI protocol, so they currently work with
Xavante, CGI and Fastcgi. It includes a launcher that makes it easy to launch a
Xavante instance for development.
The easiest way to install Orbit is using LuaRocks. Luarocks install orbit is the
command for installing. For this, you need to install LuaRocks first.
If you haven't installed all the dependencies, here are the steps to be followed to
setup Orbit in Unix/Linux environment.
106
Lua
Installing Apache
Connect to your server. Install Apache2, its support modules and enable
required Apache2 modules using:
Install LuaRocks
$ sudo apt-get install luarocks
Setting up Apache2
$ sudo raj /etc/apache2/sites-available/default
Add this following section below the <Directory /var/www/> section of the config
file. If this section has an 'AllowOverride None' then you need to change the
'None' to 'All' so that the .htaccess file can override the configuration locally.
<IfModule mod_fcgid.c>
AddHandler fcgid-script .lua
AddHandler fcgid-script .ws
AddHandler fcgid-script .op
FCGIWrapper "/usr/local/bin/wsapi.fcgi" .ws
FCGIWrapper "/usr/local/bin/wsapi.fcgi" .lua
FCGIWrapper "/usr/local/bin/op.fcgi" .op
#FCGIServer "/usr/local/bin/wsapi.fcgi" -idle-timeout 60 -processes 1
#IdleTimeout 60
#ProcessLifeTime 60
107
Lua
</IfModule>
Restart the server to ensure the changes made comes into effect.
To enable your application, you need to add +ExecCGI to an .htaccess file in the
root of your Orbit application - in this case, /var/www.
Options +ExecCGI
DirectoryIndex index.ws
-- declaration
module("myorbit", package.seeall, orbit.new)
-- handler
function index(web)
return my_home_page()
end
-- dispatch
myorbit:dispatch_get(index, "/", "/index")
-- Sample page
function my_home_page()
return [[
<head></head>
<html>
<h2>First Page</h2>
</html>
]]
end
108
Lua
First Page
Orbit provides another option, i.e., Lua code can generate html.
#!/usr/bin/env index.lua
-- index.lua
require"orbit"
function generate()
return html {
head{title "HTML Example"},
body{
h2{"Here we go again!"}
}
}
end
orbit.htmlify(generate)
print(generate())
Creating Forms
A simple form example is shown below:
#!/usr/bin/env index.lua
require"orbit"
function test ()
return wrap(form (H'table' {
109
Lua
orbit.htmlify(wrap,test)
print(test())
WSAPI
As mentioned earlier, WSAPI acts as the base for many projects and have
multiple features embedded in it. You can use WSAPI and support the following
platforms,
Windows
UNIX-based systems
CGI
FastCGI
Xavante
Request processing
Output buffering
Authentication
File uploads
Request isolation
Multiplexing
110
Lua
#!/usr/bin/env wsapi.cgi
module(..., package.seeall)
function run(wsapi_env)
local headers = { ["Content-type"] = "text/html" }
You can see in the above code a simple html page is formed and returned. You
can see the usage of coroutines that makes it possible to return statement by
statement to calling function. Finally, html status code(200), headers and html
page is returned.
Xavante
Xavante is a Lua HTTP 1.1 Web server that uses a modular architecture based
on URI mapped handlers. Xavante currently offers,
File handler
Redirect handler
WSAPI handler
File handler is used for general files. Redirect handler enables URI remapping
and WSAPI handler for handing with WSAPI applications.
require "xavante.filehandler"
111
Lua
require "xavante.cgiluahandler"
require "xavante.redirecthandler"
local simplerules = {
{ -- cgiluahandler example
match = {"%.lp$", "%.lp/.*$", "%.lua$", "%.lua/.*$" },
with = xavante.cgiluahandler.makeHandler (webDir)
},
{ -- filehandler example
match = ".",
with = xavante.filehandler,
params = {baseDir = webDir}
},
}
xavante.HTTP{
server = {host = "*", port = 8080},
defaultHost = {
rules = simplerules
},
}
112
Lua
To use virtual hosts with Xavante, the call to xavante.HTTP would be changed to
something like as follows:
xavante.HTTP{
server = {host = "*", port = 8080},
defaultHost = {},
virtualhosts = {
["www.sitename.com"] = simplerules
}
}
Rings, a library which provides a way to create new Lua states from
within Lua.
Ending Note
There are so many Lua based web frameworks and components available for us
and based on the need, it can be chosen. There are other web frameworks
available which include the following:
113
Lua
Lua Server Pages, a Lua scripting engine plug-in that blows away any
other approach to embedded web development, offers a dramatic short
cut to traditional C server pages.
These web frameworks can leverage your web applications and help you in doing
powerful operations.
114
Lua
For simple data operations, we may use files, but sometimes, these file
operations may not be efficient, scalable, and powerful. For this purpose, we
may often switch to using databases. LuaSQL is a simple interface from Lua to a
number of database management systems. LuaSQL is the library, which provides
support for different types of SQL. This include,
SQLite
Mysql
ODBC
MySQL db Setup
In order to use the following examples to work as expected, we need the initial
db setup. The assumptions are listed below.
You have installed and setup MySQL with default user as root and
password as '123456'.
Importing MySQL
We can use a simple require statement to import the sqlite library assuming
that your Lua implementation was done correctly.
The variable mysql will provide access to the functions by referring to the main
mysql table.
Setting up Connection
We can set up the connection by initiating a MySQL environment and then
creating a connection for the environment. It is shown below.
115
Lua
The above connection will connect to an existing MySQL file and establishes the
connection with the newly created file.
Execute Function
There is a simple execute function available with the connection that will help us
to do all the db operations from create, insert, delete, update and so on. The
syntax is shown below:
In the above syntax, we need to ensure that conn is open and existing MySQL
connection and replace the 'MySQLSTATEMENT' with the correct statement.
When you run the above program, a table named sample will be created with
two columns namely, id and name.
In case there is any error, you would be returned an error statement instead of
nil. A simple error statement is shown below.
116
Lua
LuaSQL: Error executing query. MySQL: You have an error in your SQL
syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near '"id INTEGER, name TEXT)' at line 1
In the above code, conn is an open MySQL connection. With the help of the
cursor returned by the execute statement, you can loop through the table
response and fetch the required select data.
117
Lua
A Complete Example
A complete example including all the above statements is given below.
When you run the above program, you will get the following output.
Performing Transactions
Transactions are a mechanism that ensures data consistency. Transactions
should have the following four properties:
Transaction starts with START TRANSACTION; and ends with commit or rollback
statement.
Start Transaction
In order to initiate a transaction, we need to execute the following statement in
Lua, assuming conn is an open MySQL connection.
conn:execute([[START TRANSACTION;]])
Rollback Transaction
We need to execute the following statement to rollback changes made after start
transaction is executed.
conn:execute([[ROLLBACK;]])
Commit Transaction
We need to execute the following statement to commit changes made after start
transaction is executed.
conn:execute([[COMMIT;]])
We have known about MySQL in the above and following section explains about
basic SQL operations. Remember transactions, though not explained again for
SQLite3 but the same statements should work for SQLite3 as well.
119
Lua
Importing SQLite
We can use a simple require statement to import the SQLite library assuming
that your Lua implementation was done correctly. During installation, a folder
libsql that contains the database related files.
The variable sqlite3 will provide access to the functions by referring to the main
sqlite3 table.
Setting Up Connection
We can set up the connection by initiating an SQLite environment and then
creating a connection for the environment. It is shown below.
The above connection will connect to an existing SQLite file or creates a new
SQLite file and establishes the connection with the newly created file.
Execute Function
There is a simple execute function available with the connection that will help us
to do all the db operations from create, insert, delete, update and so on. The
syntax is shown below:
In the above syntax, we need to ensure that conn is open and existing sqlite3
connection and replace the 'SQLite3STATEMENT' with the correct statement.
120
Lua
When you run the above program, a table named sample will be created with
two columns namely, id and name.
In the above code, conn is an open sqlite3 connection. With the help of the
cursor returned by the execute statement, you can loop through the table
response and fetch the required select data.
A Complete Example
A complete example including all the above statements is given below.
121
Lua
When you run the above program, you will get the following output.
122
Lua
We can execute all the available queries with the help of this libsql library. So,
please don't stop with these examples. Experiment various query statement
available in respective MySQL, SQLite3 and other supported db in Lua.
123
Lua
Lua is used in a lot of game engines due to its simple language structure and
syntax. The garbage collection feature is often quite useful in games which
consume a lot of memory due to rich graphics that is used. Some game engines
that use Lua includes:
Corona SDK
Gideros Mobile
ShiVa3D
Moai SDK
LOVE
CryEngine
Each of these game engines are based on Lua and there is a rich set of API
available in each of these engines. We will look at the capabilities of each in
brief.
Corona SDK
Corona SDK is a cross platform mobile game engine that supports iPhone, iPad,
and Android platforms. There is a free version of Corona SDK that can be used
for small games with limited features. You can upgrade to other versions when
needed.
Ads API
Analytics API
It is easier and faster to develop an application using the above APIs rather than
using the native APIs separately for iOS and Android.
124
Lua
Gideros Mobile
Gideros provides the cross-platform SDK to create games for iOS and Android. It
is free to use with a made with Gideros splash. Some of the striking advantages
in Gideoros includes the following:
Plugins: You can easily extend the core with plugins. Import your existing
(C, C++, Java or Obj-C) code, bind to Lua and interpret them directly.
Dozens of open-source plugins are already developed and ready to use.
Clean OOP approach: Gideros provides its own class system with all the
basic OOP standards, enabling you to write clean and reusable code for
any of your future games.
Native speed: Developed on top of C/C++ and OpenGL, your game runs
at native speed and fully utilizes the power of CPUs and GPUs underneath.
ShiVa3D
ShiVa3D is one of 3D game engines which provides a graphical editor designed
to create applications and video games for the Web, Consoles and Mobile
devices. It supports multiple platforms which includes, Windows, Mac, Linux,
iOS, Android, BlackBerry, Palm OS, Wii and WebOS.
Standard plugins
IDE
The web edition of Shiva3d is completely free and other editions you have
subscribe.
125
Lua
Moai SDK
Moai SDK is a cross platform mobile game engine that supports iPhone, iPad,
and Android platforms. Moai platform initially consisted of Moai SDK, an open
source game engine, and Moai Cloud, a cloud platform as a service for the
hosting and deployment of game services. Now the Moai Cloud is shut down and
only the game engine is available.
Moai SDK runs on multiple platforms including iOS, Android, Chrome, Windows,
Mac and Linux.
LOVE
LOVE is a framework that you can use to make 2D games. It is free and open-
source. It supports Windows, Mac OS X and Linux platforms.
Audio API
Math API
Physics API
CryEngine
CryEngine is a game engine developed by the German game developer Crytek.
It has evolved from generation 1 to generation 4 and is an advanced
development solution. It supports PC, Xbox 360, PlayStation3 and WiiU games.
Visual effects like Natural Lighting & Dynamic Soft Shadows, Real-time
Dynamic Global Illumination, Light Propagation Volume, Particle Shading,
Tessellation and so on.
126
Lua
In Game Mixing & Profiling, Data-driven Sound System Dynamic Sounds &
Interactive Music and so on.
An Ending Note
Each of these Game SDKs/frameworks have their own advantages and
disadvantages. A proper choice between them makes your task easier and you
can have a better time with it. So, before using it, you need to know the
requirements for your game and then analyze which satisfies all your needs and
then should use them.
127
Lua
Lua standard libraries provide a rich set of functions that is implemented directly
with the C API and is in-built with Lua programming language. These libraries
provide services within the Lua programming language and also outside services
like file and db operations.
Modules library
String manipulation
Table manipulation
Math library
Debug facilities
Basic Library
We have used the basic library throughout the tutorial under various topics. The
following table provides links of related pages and lists the functions that are
covered in various part of this Lua tutorial
1. Error Handling
2. Memory Management
3. dofile ([filename])
128
Lua
It opens the file and executes the contents of the file as a chunk. If no
parameter is passed, then this function executes the contents of
standard input. The errors will be propagated to the caller.
4. _G
Thus is the global variable that holds the global environment (that is,
_G._G = _G). Lua itself does not use this variable.
5. getfenv ([f])
6. getmetatable (object)
7. ipairs (t)
Loads a chunk using function func to get its pieces. Each call to func
must return a string that concatenates with previous results.
9. loadfile ([filename]))
Similar to load, but gets the chunk from file filename or from the
standard input, if no file name is given.
Similar to load, but gets the chunk from the given string.
129
Lua
130
Lua
Sets the metatable for the given table. (You cannot change the
metatable of other types from Lua, only from C.) If metatable is nil,
removes the metatable of the given table. If the original metatable has
a "__metatable" field, raises an error. This function returns table.
Returns the type of its only argument, coded as a string. The possible
results of this function are "nil" (a string, not the value nil), "number",
"string", "boolean", "table", "function", "thread", and "userdata".
24. _VERSION
25. Coroutines
Modules Library
The modules library provides the basic functions for loading modules in Lua. It
exports one function directly in the global environment: require. Everything else
is exported in a table package. The details about the modules library is explained
in the earlier chapter Lua - Modules tutorial.
131
Lua
String manipulation
Lua provides a rich set of string manipulation functions. The earlier Lua -
Strings tutorial covers this in detail.
Table manipulation
Lua depends on tables in almost every bit of its operations. The earlier Lua -
Tables tutorial covers this in detail.
Debug facilities
Lua provides a debug library which provides all the primitive functions for us to
create our own debugger. It is discussed in earlier Lua - Debugging tutorial.
132
Lua
1. math.abs (x)
2. math.acos (x)
3. math.asin (x)
4. math.atan (x)
5. math.atan2 (y, x)
Returns the arc tangent of y/x (in radians), but uses the signs of both
parameters to find the quadrant of the result. (It also handles correctly
the case of x being zero.)
6. math.ceil (x)
7. math.cos (x)
8. math.cosh (x)
9. math.deg (x)
133
Lua
14. math.huge
Returns two numbers, the integral part of x and the fractional part of x.
21. math.pi
Returns xy. (You can also use the expression x^y to compute this
value.)
134
Lua
Returns the square root of x. (You can also use the expression x^0.5 to
compute this value.)
Trigonometric Functions
A simple example using trigonometric function is shown below.
radianVal = math.rad(math.pi / 2)
io.write(radianVal,"\n")
135
Lua
When we run the above program, we will get the following output.
0.027415567780804
0.0
1.0
0.0
1.0
180
-- Floor
io.write("Floor of 10.5055 is ", math.floor(10.5055),"\n")
-- Ceil
io.write("Ceil of 10.5055 is ", math.ceil(10.5055),"\n")
-- Square root
io.write("Square root of 16 is ",math.sqrt(16),"\n")
-- Power
io.write("10 power 2 is ",math.pow(10,2),"\n")
io.write("100 power 0.5 is ",math.pow(100,0.5),"\n")
-- Absolute
io.write("Absolute value of -10 is ",math.abs(-10),"\n")
--Random
math.randomseed(os.time())
io.write("Random number between 1 and 100 is ",math.random(),"\n")
--Random between 1 to 100
io.write("Random number between 1 and 100 is ",math.random(1,100),"\n")
--Max
136
Lua
When we run the above program, we will get the following output.
Floor of 10.5055 is 10
Ceil of 10.5055 is 11
Square root of 16 is 4
10 power 2 is 100
100 power 0.5 is 10
Absolute value of -10 is 10
Random number between 1 and 100 is 0.22876674703207
Random number between 1 and 100 is 7
Maximum in the input array is 999
Minimum in the input array is 1
The above examples are just a few of the common examples. We can use math
library based on our need, so try using all the functions to be more familiar.
137
Lua
1. os.clock ()
4. os.execute ([command])
Calls the ANSI C function exit to terminate the host program. If code is
true, the returned status is EXIT_SUCCESS; if code is false, the
returned status is EXIT_FAILURE; if code is a number, the returned
status is this number.
6. os.getenv (varname)
7. os.remove (filename)
Deletes the file (or empty directory, on POSIX systems) with the given
name. If this function fails, it returns nil, plus a string describing the
error and the error code.
138
Lua
fails, it returns nil, plus a string describing the error and the error code.
11. os.tmpname ()
Returns a string with a file name that can be used for a temporary file.
The file must be explicitly opened before its use and explicitly removed
when no longer needed.
Common OS functions
A simple example using common math functions is shown below.
-- Time
io.write("The OS time is ", os.time(),"\n")
139
Lua
When we run the above program, we will get similar output to the following.
The above examples are just a few of the common examples, we can use OS
library based on our need, so try using all the functions to be more familiar.
There are functions like remove which helps in removing file, execute that helps
us executing OS commands as explained above.
140