Programming in Lua (First Edition) This Is an Online Version of the First Edition of the Book
Total Page:16
File Type:pdf, Size:1020Kb
Programming in Lua (first edition) This is an online version of the first edition of the book Programming in Lua by Roberto Ierusalimschy Lua.org, December 2003 ISBN 85-903798-1-7 The book is a detailed and authoritative introduction to all aspects of Lua programming, by Lua's chief architect. The first edition was aimed at Lua 5.0 and remains largely relevant. If you find this online version useful, please consider buying a copy of the second edition, which updates the text to Lua 5.1 and brings substantial new material. This helps to support the Lua project. For the official definition of the Lua language, see the reference manual. Copyright © 2003-2004 Roberto Ierusalimschy. All rights reserved. This online book is for personal use only. It cannot be copied to other web sites or further distributed in any form. Contents Part I · The Language • 1 - Getting Started • 1.1 - Chunks • 1.2 - Global Variables • 1.3 - Some Lexical Conventions • 1.4 - The Stand-Alone Interpreter • 2 - Types and Values • 2.1 - Nil • 2.2 - Booleans • 2.3 - Numbers • 2.4 - Strings • 2.5 - Tables • 2.6 - Functions • 2.7 - Userdata and Threads • 3 - Expressions • 3.1 - Arithmetic Operators • 3.2 - Relational Operators • 3.3 - Logical Operators • 3.4 - Concatenation • 3.5 - Precedence • 3.6 - Table Constructors • 4 - Statements • 4.1 - Assignment • 4.2 - Local Variables and Blocks • 4.3 - Control Structures • 4.3.1 - if then else • 4.3.2 - while • 4.3.3 - repeat • 4.3.4 - Numeric for • 4.3.5 - Generic for • 4.4 - break and return • 5 - Functions • 5.1 - Multiple Results • 5.2 - Variable Number of Arguments • 5.3 - Named Arguments • 6 - More about Functions • 6.1 - Closures • 6.2 - Non-Global Functions • 6.3 - Proper Tail Calls • 7 - Iterators and the Generic for • 7.1 - Iterators and Closures • 7.2 - The Semantics of the Generic for • 7.3 - Stateless Iterators • 7.4 - Iterators with Complex State • 7.5 - True Iterators • 8 - Compilation, Execution, and Errors • 8.1 - The require Function • 8.2 - C Packages • 8.3 - Errors • 8.4 - Error Handling and Exceptions • 8.5 - Error Messages and Tracebacks • 9 - Coroutines • 9.1 - Coroutine Basics • 9.2 - Pipes and Filters • 9.3 - Coroutines as Iterators • 9.4 - Non-Preemptive Multithreading • 10 - Complete Examples • 10.1 - Data Description • 10.2 - Markov Chain Algorithm • • Part II · Tables and Objects • 11 - Data Structures • 11.1 - Arrays • 11.2 - Matrices and Multi-Dimensional Arrays • 11.3 - Linked Lists • 11.4 - Queues and Double Queues • 11.5 - Sets and Bags • 11.6 - String Buffers • 12 - Data Files and Persistence • 12.1 - Serialization • 12.1.1 - Saving Tables without Cycles • 12.1.2 - Saving Tables with Cycles • 13 - Metatables and Metamethods • 13.1 - Arithmetic Metamethods • 13.2 - Relational Metamethods • 13.3 - Library-Defined Metamethods • 13.4 - Table-Access Metamethods • 13.4.1 - The __index Metamethod • 13.4.2 - The __newindex Metamethod • 13.4.3 - Tables with Default Values • 13.4.4 - Tracking Table Accesses • 13.4.5 - Read-Only Tables • 14 - The Environment • 14.1 - Accessing Global Variables with Dynamic Names • 14.2 - Declaring Global Variables • 14.3 - Non-Global Environments • 15 - Packages • 15.1 - The Basic Approach • 15.2 - Privacy • 15.3 - Packages and Files • 15.4 - Using the Global Table • 15.5 - Other Facilities • 16 - Object-Oriented Programming • 16.1 - Classes • 16.2 - Inheritance • 16.3 - Multiple Inheritance • 16.4 - Privacy • 16.5 - The Single-Method Approach • 17 - Weak Tables • 17.1 - Memoize Functions • 17.2 - Object Attributes • 17.3 - Revisiting Tables with Default Values • Part III · The Standard Libraries • 18 - The Mathematical Library • 19 - The Table Library • 19.1 - Array Size • 19.2 - Insert and Remove • 19.3 - Sort • 20 - The String Library • 20.1 - Pattern-Matching Functions • 20.2 - Patterns • 20.3 - Captures • 20.4 - Tricks of the Trade • 21 - The I/O Library • 21.1 - The Simple I/O Model • 21.2 - The Complete I/O Model • 21.2.1 - A Small Performance Trick • 21.2.2 - Binary Files • 21.3 - Other Operations on Files • 22 - The Operating System Library • 22.1 - Date and Time • 22.2 - Other System Calls • 23 - The Debug Library • 23.1 - Introspective Facilities • 23.1.1 - Accessing Local Variables • 23.1.2 - Accessing Upvalues • 23.2 - Hooks • 23.3 - Profiles • Part IV · The C API • 24 - An Overview of the C API • 24.1 - A First Example • 24.2 - The Stack • 24.2.1 - Pushing Elements • 24.2.2 - Querying Elements • 24.2.3 - Other Stack Operations • 24.3 - Error Handling with the C API • 24.3.1 - Error Handling in Application Code • 24.3.2 - Error Handling in Library Code • 25 - Extending your Application • 25.1 - Table Manipulation • 25.2 - Calling Lua Functions • 25.3 - A Generic Call Function • 26 - Calling C from Lua • 26.1 - C Functions • 26.2 - C Libraries • 27 - Techniques for Writing C Functions • 27.1 - Array Manipulation • 27.2 - String Manipulation • 27.3 - Storing State in C Functions • 27.3.1 - The Registry • 27.3.2 - References • 27.3.3 - Upvalues • 28 - User-Defined Types in C • 28.1 - Userdata • 28.2 - Metatables • 28.3 - Object-Oriented Access • 28.4 - Array Access • 28.5 - Light Userdata • 29 - Managing Resources • 29.1 - A Directory Iterator • 29.2 - An XML Parser 1 - Getting Started To keep with the tradition, our first program in Lua just prints "Hello World": print("Hello World") If you are using the stand-alone Lua interpreter, all you have to do to run your first program is to call the interpreter (usually named lua) with the name of the text file that contains your program. For instance, if you write the above program in a file hello.lua, the following command should run it: prompt> lua hello.lua As a slightly more complex example, the following program defines a function to compute the factorial of a given number, asks the user for a number, and prints its factorial: -- defines a factorial function function fact (n) if n == 0 then return 1 else return n * fact(n-1) end end print("enter a number:") a = io.read("*number") -- read a number print(fact(a)) If you are using Lua embedded in an application, such as CGILua or IUPLua, you may need to refer to the application manual (or to a "local guru") to learn how to run your programs. Nevertheless, Lua is still the same language; most things that we will see here are valid regardless of how you are using Lua. For a start, we recommend that you use the stand-alone interpreter (that is, the lua executable) to run your first examples and experiments. 1 - Getting Started To keep with the tradition, our first program in Lua just prints "Hello World": print("Hello World") If you are using the stand-alone Lua interpreter, all you have to do to run your first program is to call the interpreter (usually named lua) with the name of the text file that contains your program. For instance, if you write the above program in a file hello.lua, the following command should run it: prompt> lua hello.lua As a slightly more complex example, the following program defines a function to compute the factorial of a given number, asks the user for a number, and prints its factorial: -- defines a factorial function function fact (n) if n == 0 then return 1 else return n * fact(n-1) end end print("enter a number:") a = io.read("*number") -- read a number print(fact(a)) If you are using Lua embedded in an application, such as CGILua or IUPLua, you may need to refer to the application manual (or to a "local guru") to learn how to run your programs. Nevertheless, Lua is still the same language; most things that we will see here are valid regardless of how you are using Lua. For a start, we recommend that you use the stand-alone interpreter (that is, the lua executable) to run your first examples and experiments. 1.1 - Chunks Each piece of code that Lua executes, such as a file or a single line in interactive mode, is a chunk. More specifically, a chunk is simply a sequence of statements. A semicolon may optionally follow any statement. Usually, I use semicolons only to separate two or more statements written in the same line, but this is just a convention. Line breaks play no role in Lua's syntax; for instance, the following four chunks are all valid and equivalent: a = 1 b = a*2 a = 1; b = a*2; a = 1 ; b = a*2 a = 1 b = a*2 -- ugly, but valid A chunk may be as simple as a single statement, such as in the "hello world" example, or it may be composed of a mix of statements and function definitions (which are assignments actually, as we will see later), such as the factorial example. A chunk may be as large as you wish. Because Lua is used also as a data-description language, chunks with several megabytes are not uncommon. The Lua interpreter has no problems at all with large sizes. Instead of writing your program to a file, you may run the stand-alone interpreter in interactive mode. If you call Lua without any arguments, you will get its prompt: Lua 5.0 Copyright (C) 1994-2003 Tecgraf, PUC-Rio > Thereafter, each command that you type (such as print "Hello World") executes immediately after you press <enter>. To exit the interactive mode and the interpreter, just type end-of-file (ctrl-D in Unix, ctrl-Z in DOS/Windows), or call the exit function, from the Operating System library (you have to type os.exit()<enter>).