Introdução à Linguagem de Programação Lua
Tags: Lua, language, programming, tutorial
Published: 2020-04-19 17:31:28

Lua 5.3
=

Conceitos Básicos
==

Lua é uma linguagem de programação *multiparadigma*, *interpretada* (executa bytecodes em uma VM baseada em registradores [*register-based virtual machine*]), tipagem dinâmica e gerenciamento automático de memória com *incremental garbage collection*. 
Lua é uma linguagem escrita em *C ANSI*.


**Dinamicamente tipada:** Variáveis em Lua não tem tipos, apenas valores. Não há definição de tipos na linguagem para as variáveis. 

Tipos
==

Todos os valores em Lua são *first-class values*. 

Lua tem **8** tipos básicos: `nil`, `boolean`, `number`, `string`, `function`, `userdata`, `thread` e `table`.

**`nil`**: tem valor único = `nil`, que deve ser diferente de qualquer outro valor. Representa ausência de valor. 

**`boolean`**: tem dois valores, `true` e `false`, `nil` e `false` tornam uma condição falsa, qualquer outro valor é `true`.

**`number`**: representa tanto números inteiros (*integer*) quanto números reais (*floating-point*). (O tipo `number` usa duas representações internas, ou dois *subtypes*: `int` e `float`, por padrão os dois 64-bit).

**`string`**: representa uma sequência imutável de *bytes*. Também é *8-bit clean*, suporta qualquer valor de *8-bit*.

**`function`**: maneira de representar e manipular funções escritas em Lua e também em C. 

**`userdata`**: permite que dados em C sejam armazenados um bloco de memória (*raw memory*) em Lua (apenas pode ser usado pela API C).

**`thread`**: representa *threads* independentes e é usado para implementar corotinas (*coroutines* ou *collaborative multithreading*).
 
**`table`**: Implementa *associative array*, ou seja, um vetor associativo que pode ter como índices não apenas números, mas qualquer valor de Lua, exceto `nil`. As tabelas podem ser heterogêneas; isto é, eles podem conter valores de todos os tipos (exceto `nil`). Qualquer chave com valor nulo não é considerada parte da tabela. Por outro lado, qualquer chave que não faça parte de uma tabela tem um valor nulo associado. **As tabelas são o único mecanismo de estruturação de dados** em Lua; podem ser usadas ​​para representar *arrays* (vetores e matrizes), *lists*, *symbol tables*, *sets*, *records*, *graphs*, *trees*, *hash table*, etc.

Elementos Léxicos
==

Os identificadores em Lua podem ser qualquer sequência de letras, dígitos e sublinhados (*underscore*), não começando com um dígito e não sendo uma palavra reservada da linguagem. 

Lua é uma linguagem *case sensitive*, ou seja, diferencia letras maiúsculas e minúsculas. Por convenção, deve-se evitar o uso de identificadores com *underscore* e letra maiúsculas, como por exemplo: `_VERSION`.

Comentários curtos (uma linha) são feitos com `--` (dois hífens), para comentários longos (mais de uma linha) se utiliza dois traços seguidos de dois colchetes de abertura `--[[` e dois colchetes de fechamento `]]`, veja o exemplo abaixo:

```lua
-- comentário de uma linha

--[[ comentário
em duas linhas
--]]
```

Palavras Reservadas
===

Lua possui **22** palavras reservadas, são elas:


|       |       |          |       |        |        |
|:-------:|:-------:|:----------:|:-------:|:--------:|:--------:|
|  and  | break |    do    |  else | elseif |   end  |
| false |  for  | function |  goto |   if   |   in   |
| local |  nil  |    not   |   or  | repeat | return |
|  then |  true |   until  | while |        |        |

 Outros *tokens* da linguagem:

|    |    |    |    |    |     |    |
|:----:|----:|:----:|:----:|:----:|:-----:|:----:|
| +  | -  | *  | /  | %  | ^   | #  |
| &  | ~  | |  | << | >> | //  |    |
| == | ~= | <= | >= | <  | >   | =  |
| (  | )  | {  | }  | [  | ]   | :: |
| ;  | :  | ,  | .  | .. | ... |    |

Variável
===


Existem 3 tipos de variáveis: variáveis **globais**, variáveis **locais** e **campos da tabela**. Todas as variáveis por padrão tem **escopo global**, a menos que declarada explicitamente como local. Antes da primeira atribuição a uma variável, seu valor é `nil`.

Criando variáveis:

```lua
var1 = 33 -- tipo number, int
var2 = 33.0 -- tipo number, float

ok = true -- tipo boolean, valor verdadeiro
nao_ok = false -- tipo boolean, valor falso

lang = 'Linguagem Lua' -- tipo string, usando aspas duplas
lang = 'Linguagem Lua' -- tipo string, usando aspas simples
-- string com mais de uma linha, se usa colchetes
lang = [[Linguagem de
programação Lua]]

-- table
lista = {1.33, 5.8, 7.8} -- tipo table
lista2 = {1, 5, 10, 1000} -- tipo table
agenda = {pedro = '1234-4321', amanda = '5555-5555'}
```

Para criar **variáveis locais**, é necessário usar a palavra reservada `local`, veja:

```lua
local var1 = 44.5
local lista = {1, 4, 5, 6}
```

Lua permite múltiplas atribuições, do lado esquerdo uma lista de variáveis e do lado direito uma lista de expressões, os elementos são separados por vírgula:
```lua
-- a tem o valor 100
-- b tem o valor 200.5
-- c tem o valor 'lua'
a, b, c = 100, 200.5, 'Lua'

-- swap
a, b = 1, 2 -- a = 1, b = 2
a, b = b, a -- a = 2, b = 1
```

Operações Matemáticas
===

Lua suporta as seguintes operações aritméticas:

|          descrição         | operador | exemplo |
|:--------------------------:|:--------:|:-------:|
|            soma            |     +    |  a + b  |
|          subtração         |     -    |  a - b  |
|        multiplicação       |     *    |  a * b  |
|           divisão          |     /    |  a / b  |
|       divisão inteira      |    //    |  a // b |
|           módulo           |     %    |  a % b  |
|        exponenciação       |     ^    |  a ^ b  |
| negativo (operador unário) |     -    |    -a   |

Com exceção do operador de exponenciação `^` e de divisão inteira `//`, os operadores aritméticos funcionam da seguinte maneira: 

- Se os dois operandos são números inteiros (*int*), a operação é executada sobre números inteiros e o resultado é um número inteiro. 

- Caso contrário, se ambos os operandos forem *números* ou *strings* que podem ser convertidos em números, eles serão convertidos em *float*, a operação será executada seguindo as regras usuais para aritmética de *ponto flutuante*, e o resultado é um *float*.

A exponenciação `^` e a divisão `/` sempre convertem seus operandos em *float* e o resultado é sempre *float*.
 
A divisão inteira `//` é uma divisão que arredonda pra baixo o número. 

Módulo `%` é o resto da divisão inteira.

Divisão por `0` (zero) não gera uma exceção, mas retorna um valor numérico `inf`

**`inf`** = valor infinito, por exemplo
```lua
10/0 -- retorna inf
```

**`nan`** = *Not a Number*, é um valor especial usado para representar resultados numéricos indefinidos ou não representáveis, por exemplo:
```lua
0/0 -- nan
```

Operadores Relacionais
===

Lua suporta os seguintes operadores relacionais:

|        descrição        | operador | exemplo |
|:-----------------------:|:--------:|:-------:|
|        igualdade        |    ==    |  a == a |
| desigualdade(diferente) |    ~=    |  a ~= b |
|        menor que        |     <    |  a < b  |
|        maior que        |    >     |  a > b  |
|      menor ou igual     |    <=    |  a <= b |
|      maior ou igual     |    >=    |  a >= b |

Todos os operadores retornam um valor tipo `boolean`, que pode ser `true` ou `false`.

A igualdade `==` primeiro compara o tipo de seus operandos. Se os tipos forem diferentes, o resultado será falso. Caso contrário, os valores dos operandos são comparados. 

`Table`, `userdata` e `threads` são comparados por referência: dois objetos são considerados iguais apenas se forem o mesmo objeto. Sempre que você cria um novo objeto esse novo objeto é diferente de qualquer objeto existente anteriormente. 

O operador `~=` é a negação da igualdade `==`.

As comparações de igualdade `==` não converte `string` para `number`, ou `number` para `string`. Sempre irá retornar `false`, e o operador `~=` retorna `true`:
```lua
'0' == 1 -- false
'0' == 0 -- false
'0' ~= 1 -- true
'0' ~= 0 -- true
```

Seguindo o padrão *IEEE 754*, o `nan` é considerado nem menor, nem igual, nem maior que qualquer valor (incluindo ele próprio).

Operadores bit-a-bit
===

Lua suporta os seguintes operadores bit-a-bit:


|       descrição      | operador |
|:--------------------:|:--------:|
|      bitwise AND     |     &    |
|      bitwise OR      |     |    |
| bitwise exclusive OR |     ~    |
|      right shift     |    >>    |
|      left shift      |    <<    |
|   unary bitwise NOT  |     ~    |


Operadores lógicos
===

Os operadores lógicos em Lua são `and`, `or`, e `not`. 

| descrição                | operador | exemplo |
|:--------------------------:|:----------:|:---------:|
| e (conjunção)            | and      | a and b |
| ou (disjunção inclusiva) | or       | a or b  |
| não (negado)             | not      | not a   |

Todos os operadores lógicos consideram `false` e `nil` como `false` e qualquer outra coisa como `true`. As expressões lógicas são avaliadas por curto-circuito (*short-circuit evaluation*), ou seja, o segundo operando é avaliado apenas se necessário. aqui estão alguns exemplos:

O operador de negação (`not`) sempre retorna `true` ou `false`. 

O operador `and` retorna seu primeiro argumento se esse valor for `false` ou `nil`, caso contrário, e retorna seu segundo argumento. 

O operador `or` retorna seu primeiro argumento se esse valor for diferente de `nil` e `false`; caso contrário, `or` retorna seu segundo argumento. 

Vejamos os exemplos abaixo com `nan`, `inf` e `nil`:

**`or`**:
```lua
2 or nil -- 2
nil or 2 -- 2
2 or nan -- 2
nan or 2 -- 2
'Lua' or nil -- 'Lua'
'Lua' or nan -- 'Lua'
'Lua' or inf -- 'Lua'
2 or error() -- 2
```

**`and`**:
```lua
2 and nil -- nil
nil and 2 -- 2
2 and nan - nil
nan and 2 -- nil
'Lua' and nil -- nil
'Lua' and nan -- nan
'Lua' and inf -- inf
```

**`not`**:
```lua
not 2 -- false
not 'lua' -- false
not nil -- true
not nan -- true
not inf -- true
not not 2 -- true
not true -- false
not false -- true
```

Precedência
===

A precedência de operadores em Lua, do maior para o menor:

- parênteses: `(`, `)`
- exponenciação: `^`
- operadores unários: `not`, `#`, `-`, `~`
- multiplicação: `*`
- divisão: `/`
- divisão inteira: `//`
- módulo: `%`
- adição: `+`
- subtração: `-`
- concatenação de string: `..`
- operadores *bit a bit*: `<<`, `>>`, `&`, `~`, `|`
- operadores relacionais: `<`, `>`, `<=`, `>=`, `~=`, `==` 
- operadores lógicos: `and`, `or` 

Os operadores de concatenação `..` e exponenciação `^` são associativos-à-direita. E todos os outros operadores binários são associativos-à-esquerda.

Estruturas de Controle
==

Em Lua temos estruturas de decisão (condicional) e de repetição, semelhante a qualquer outra linguagem de programação. (Lua a partir da versão 5.2 incluiu o comando `goto`).

Estrutura Condicional
===

```lua
--[[ *exp* é qualquer trecho de código Lua 
que está realizando alguma operação lógica. 
Em uma expressão os valores em Lua como nil 
e false sempre retornam false, qualquer 
outro valor retorna true.
*block* é qualquer trecho de código Lua que 
será executado somente dentro do corpo do condicional
--]]

-- if na mesma linha
if exp then block end

-- ou
if exp then 
  block 
end

-- usando else if (se senão então) na mesma linha
if exp then block elseif exp then block else block end

-- ou
if exp then 
  block
elseif exp then
  block
else
  block
end
```

Estrutura de Repetição
===

Para os nossos *loops* usamos os clássicos `while`, `repeat–until` e `for`.

Usando `while` e `repeat–until`
====

```lua
-- while: enquanto *exp* for verdadeira faça
-- no while verifica a *exp* primeiro, depois executa *block*

-- mesma linha
while exp do block end

-- ou
while exp do
  block
end

-- repeat–until, repita até que *exp* seja verdadeira
-- em repeat primeiro executa o bloco e depois verifica a exp

-- mesma linha	
repeat block until exp do

-- ou
repeat
  block
until exp
```

Usando o `for`
====

O loop `for` em Lua tem duas formas diferentes, uma é um *for numérico* e outra um *for genérico* (veja as funções `pairs` e `ipairs` na seção sobre *funções Embutidas*):

for numérico
```lua 
-- inicial = número inicial
-- limite = número limite
for var = inicial, limite do 
  block
end

-- ou na mesma linha
for var = inicial, limite do block end
``` 

Há um terceiro parâmetro opcional: passo (step), 
```lua
--[[ passo tem um valor padrão de 1, 
pois o loop vai de 1 em 1 iterando 
os elementos do valor inicial ao limite, 
se mudarmos para 2, a iteração será de 2 em 2
--]]

for var = inicial, limite, passo do
	block
end

-- na mesma linha
for var = inicial, limite, passo do block end

-- exemplo
for i = 1, 10, 2 do
	print(i)
end

- ou na mesma linha
for i = 1, 10, 2 do print(i) end

-- saida: 1, 3, 5, 9

-- exemplo, tabuada do 5
for i = 1, 10 do
	print("5 x", i, "=", 5 * i)
end
--[[
saída:
5 x 1 = 5
5 x 2 = 10
5 x 3 = 15
5 x 4 = 20
5 x 5 = 25
5 x 6 = 30
5 x 7 = 35
5 x 8 = 40
5 x 9 = 45
5 x 10 = 50
--]]

```

Comando `break` 
===
Para sair (interromper) a execução de um *loop* usamos o comando `break`

```lua
-- loop infinito
while true do
  print("entrou no loop...")
  break -- interrompe na primeira iteração
  print("nunca será executado")
end

-- outro exemplo
-- observe a linha onde incrementamos nosso 'contador' i
local i = 1
while i < 10 do
    print("entrou no loop")
    if i == 3 then break end
    i = i + 1 -- incremento
end
  print(i) -- 3
--[[ saída:
entrou no loop
entrou no loop
entrou no loop
3
--]]

-- no loop for
for i = 1, 10 do
  print("entrou no loop")
  break -- interrompe
end
print("saiu do loop")

for i = 1, 10 do
  print("entrou no loop")
  if i == 3 then break end
end
print("saiu do loop")

--[[ saída:
entrou no loop
entrou no loop
entrou no loop
saiu do loop
--]]
```


Funções
==

Como todos os outros tipos em Lua, `function` também é *first-class-value*, isso significa que você pode atribuir uma função a uma variável, passar uma função por parâmetro e retornar um função como valor.

Por padrão as funções são anônimas, você atribui a função a uma variável, como por exemplo:

```lua
diga_ola = function() 
  print("olá!") 
end

-- executando
diga_ola() -- imprime "olá"

-- pode ser escrita em uma única linha
diga_ola = function() print("olá!") end

-- Lua fornece syntactic sugar para a definição
-- a função escrita abaixo é equivalente a versão de cima.
function diga_ola()
  print("olá")
end
```
Ao usar o *syntactic sugar*, Lua transcreve a função para o formato anônimo. Essas duas formas são equivalentes.

```lua 
function nome_da_funcao() block end
``` 
para 
```lua 
nome_da_funcao = function() block end
```
Funções podem ter zero ou mais parâmetros e podem ter nenhum ou múltiplos retornos (se usa no final do corpo da função a palavra reservada `return`), veja:

```lua
-- função com 2 parâmetros e 1 retorno
soma = function(a, b)
  local c = a + b
  return c
end

v1 = soma(10, 15) -- v1 = 25

-- 2 parâmetros e 2 retornos
somar_multiplar = function(a, b)
  local c = a + b
  local d = a * b
  return c, d
end

v1, v2 = somar_multiplar(34, 12) -- v1 = 46, v2 = 408
```
Funções podem receber um número variável de parâmetros(*variadic functions*), para isso, como último parâmetro use `...`, veja no exemplo:
```lua
imprimir = function(...)
  print(...)
end

imprimir(1,2,3,4,5,6) -- saída: 1  2  3  4  5  6
imprimir("lua", ".org") -- saída: lua  .org
```

O escopo de uma função por padrão é global, mas podemos alterar usando a palavra reservada `local`

```lua
local soma = function(a, b, c) return a + b + c end

v = soma(5, 3, 1) -- v = 9 
```

Tabela
===

Em Lua existe uma única estrutura de dados: `table`.

```lua
-- criando uma variavel table
a = {} -- vazia

-- usamos o operador unário # para descobrir o tamanho da table
#a -- 0

-- criando com elementos
a = {1, 2, 3, 4, 5, 6} -- funciona como um vetor

a = {1, 2, "Lua", 3, "Linguagem"} -- heterogenea

--[[ quando usado como um vetor, podemos 
acessar via colchetes passando um índice 
--]]
a[1] -- 1
a[2] -- 2
a[3] -- "Lua"
linguagem = a[3] -- linguagem = "Lua"
print(linguagem == "Lua") -- true

--[[ o índice em em Lua começa em 1 
e não em 0 como nas demais linguagens 
--]]
-- podemos colocar outro table como valor
a = {1, 2, "Lua", {"linguagem", "PUC"}, "roberto"}
#a -- tamanho: 5
a[3] -- "Lua"
a[4] -- table: 0x55a93478f110
-- acessando a tabela dentro da tabela
a[4][1] -- "linguagem"
a[4][2] -- "PUC"

a[4][3] -- indice não existe, retorna nil
nome_prof = a[5] -- roberto
print("professor:", nome_prof) -- professor: roberto
a[6] -- nil

--[[ usando table como tabela hash, 
ou (dict em Python), um par de chave-valor (key-value)
--]]

a = {nome = "Roberto", funcao = "professor"}
-- acessamos através da chave nome e operador . (ponto)
a.nome -- "Roberto"
a.funcao -- "professor"
a.outro -- nil

-- podemos acessar por colchetes
a["nome"] -- "Roberto"
a["outro"] -- nil
-- inserindo um novo par chave-valor
a.outro = "Knuth" 
-- ou de outra forma
a["outro"] = "Knuth" 

-- tabelas podem armazenar funções
somar = function(x, y) return x + y end 
a = {5, 7, somar}
a[3](a[1], a[2]) -- 12

-- usando . (ponto)
a = {}
a.valor = 5
a.valor2 = 7
a.f = somar
a.f(a.valor, a.valor2) -- 12
```

Biblioteca Padrão (*Standard Libraries*)
===

Toda linguagem de programação fornece um conjunto de bibliotecas (funções) que estão disponiveis por padrão. A Biblioteca padrão de Lua é implementada diretamente por uma API em C, e é pequena, enxuta, porém, eficiente.

Funções Embutidas
====

As funções disponíveis por padrão, ou *funções embutidas* (*built-in function*) são: `assert`, `collectgarbage`, `dofile`, `error`, `getmetatable`, `ipairs`, `load`, `loadfile`, `next`, `pairs`, `pcall`, `print`, `rawequal`, `rawget`, `rawlen`, `rawset`, `select`, `setmetatable`, `tonumber`, `tostring`, `xpcall` e `type`. E duas variáveis globais `_VERSION` e `_G`.

Funções básicas
====

`assert (v [, message])` levanta um erro (`message`) caso `v` seja falso, se `v` for verdadeiro retorna todos os argumentos:

```lua
v, m = assert(2 == 2, 'ok') -- v = true, m = 'ok'

-- v = true, m = 'ok', n = 'ok2', o = 'ok3'
v, m, n, o = assert(2 == 2, 'ok', 'ok2', 'ok3') 

-- levanta um erro
assert(false, "errado!")
stdin:1: errado!
stack traceback:
	[C]: in function 'assert'
	stdin:1: in main chunk
	[C]: in ?
```

`print (···)` recebe qual número de parâmetros e os imprime na tela:

```lua
print("Olá Lua")
Olá Lua

print("Olá", "Lua")
Olá	Lua

print("Olá", "Lua", "Linguagem")
Olá	Lua	Linguagem

-- imprime a referência da tabela
print({linguagem = "Lua"})
table: 0x559004645b70
 
a = {10, 20, 30}
print(a[3])
30
```

`type (v)` retorna uma `string` com o tipo de `v`
```lua
type(1)
number

type(1.5)
number

type('Lua')
string

type(print)
function

type({})
table

type(nil) -- retorna uma string 'nil' não o valor nil
nil

type(type(nil))
string

type(nan)
nil

> type('')
string

type(type)
function
```

`tostring(v)` converte o valor `v` para uma `string`
```lua 
tostring("aa")
aa

tostring(print)
function: 0x559002715db0

tostring("Lua")
Lua

tostring(2020)
2020

tostring(3.14)
3.14

tostring(print) -- string da referência
function: 0x559002715db0

tostring({1, 2, 3}) -- string da referência
table: 0x559004647b80
```

`tonumber (e [, base])` converte o valor `e` para `number`. Se o valor não pode ser convertido para `number` retorna `nil`.
```lua
tonumber("2.3") -- 2.3
tonumber("2,3") -- nil
tonumber("{}") -- nil
tonumber("Lua") -- nil
tonumber({}) -- nil
tonumber(print) -- nil
```

`dofile ([filename])` abre um arquivo Lua e executa seu conteúdo, se o arquivo não estiver no formato correto ocorrerá um erro.

```lua 
--[[
crie outro arquivo teste.lua, por exemplo e dentro
dele coloque códigos Lua:

soma = function(a,b) return a+b end
a, b = 4, 5
c = soma(a, b)
--]]
-- carrega e executa o arquivo
dofile("teste.lua")
print(a) -- 4
print(b) -- 5
print(c) -- 9
print(soma(3,3)) -- 6
```

`error (message [, level])` leventa um erro com o texto de `message`, por padrão `level` = `1`
```lua
error("Mensagem de Erro")
Mensagem de Erro
stack traceback:
	[C]: in function 'error'
	stdin:1: in main chunk
	[C]: in ?
```

`load (chunk [, chunkname [, mode [, env]]])` carrega um trecho de código Lua, retorna dois valores, o primeiro é uma função o segundo é `nil` caso não tenha acontecido nenhum erro, ou uma `string` com a mensagem do erro
```lua
f, err = load("x = 2 + 3")
print(x)
nil

f() -- executa o conteúdo x = 2 + 3
print(x)
5

print(err)
nil

-- com erro
f, err = load("x 2 + 3") -- erro sintático
f() -- executa o conteúdo x 2 + 3, levanta um erro
stdin:1: attempt to call a nil value (global 'f')
stack traceback:
	stdin:1: in main chunk
	[C]: in ?

print(err)
[string "x 2 + 5"]:1: syntax error near '2'
```

`loadfile ([filename [, mode [, env]]])` igual o `load()` porém carrega de um arquivo.


`pcall (f [, arg1, ···])` Executa a função `f` com os argumentos fornecidos de *modo protegido*. Isso significa que qualquer erro dentro de `f` não é propagado; em vez disso, o `pcall` captura o erro e retorna um código de status. Seu primeiro resultado é o código de status (um `boolean`), que é `true` se a chamada for bem-sucedida sem erros. Nesse caso, `pcall` também retorna todos os resultados da chamada, após este primeiro resultado. Em caso de erro, `pcall` retorna `false` mais a mensagem de erro.

```lua
soma = function(a, b) return a + b end

status, r = pcall(soma, 2, 3)

print(status)
true

print(r)
5

status, r = pcall(soma, "a", 3) -- erro

print(status)
false

print(r) -- string
stdin:1: attempt to perform arithmetic on a string value (local 'a')

-- exemplo com mais de um retorno
soma = function(a, b) return a + b, "Lua" end

status, r, r2 = pcall(soma, 2, 3)
print(status)
true

print(r)
5

print(r2)
"Lua"

-- com erro
status, r, r2 = pcall(soma, "a", 3)
print(status)
false

print(r)
stdin:1: attempt to perform arithmetic on a string value (local 'a')

-- o restante dos parâmetros ficam como nil 
print(r2)
nil
```

`xpcall (f, msgh [, arg1, ···])` Essa função é semelhante à `pcall`, exceto que define um novo manipulador de mensagens `msgh` (`function`).
```lua
erro_msg = function() return "Deu errado!" end
soma = function(a, b) return a + b end

status, r = xpcall(soma, erro_msg, 2, 3)
print(status)
true
print(r)
5
-- com erro
status, r = xpcall(soma, erro_msg, "a", 3)
print(status)
false
print(r)
Deu errado!

status, r = xpcall(soma, function() return error() end, "a", 3)
print(status)
false
print(r)
error in error handling
```

`select (index, ···)` Se `index` for um número, retornará todos os argumentos após o índice do número do argumento; um número negativo é indexado a partir do final (-1 é o último argumento). Caso contrário, o índice deve ser a `string` com '#' e o select retorna o número total de argumentos extras recebidos.
```lua
select(3, 1, 2, 3, 4, 5, 6)
3	4	5	6
select(5, 1, 2, 3, 4, 5, 6)
5	6
select('#', 1, 2, 3, 4, 5, 6)
6
select('#', 1, 2, 3)
3
select('#', {1,2,3})
1
select(1, {1,2,3})
table: 0x55a350147720

select(2, {1,2,3}) -- nil

-- usando com vararg
funcao = function(...)
  print (select(1, ...))
  print (select(2, ...))
  print ("quantidade: " .. select('#', ...))
end

funcao(1, 2, 3)
1	2	3
2	3
quantidade:3

funcao(1, 2)
1	2
2
quantidade:2
```

`next (table [, index])` Permite percorrer todos os campos de uma tabela. Seu primeiro argumento é uma tabela (`table`) e seu segundo argumento é um índice (`number`) nesta tabela. `next` retorna o próximo índice da tabela e seu valor associado. Quando chamado com `nil` como seu segundo argumento, o `next` retorna o índice inicial e seu valor associado. Quando chamado com o último índice ou com `nil` em uma tabela vazia, o `next` retorna `nil`. Se o segundo argumento estiver ausente, ele será interpretado como `nil`. Em particular, você pode usar `next(t)` para verificar se uma tabela está vazia.
```lua
tab = {10, 20, 30, 40, 50}
next(tab)
1	10
next(tab, nil)
1	10
next(tab, 1)
2	20
next(tab, 3)
4	40
next(tab, 4)
5	50
next(tab, 5)
nil
```

`rawget (table, index)` Obtém o valor real de *table[index]*, sem chamar o metamétodo `__index`. index pode ser qualquer valor.
```lua
tab = {10, 20, 30, 40, 50}
rawget(tab, 1)
10
rawget(tab, 2)
20
rawget(tab, 3)
30
rawget(tab, 4)
40
rawget(tab, 5)
50
rawget(tab, 6)
nil
```

`rawlen(v)` Retorna o tamanho do objeto `v`, pode ser uma `table` ou uma `string`, sem invocar o metamétodo `__len`. Retorna um número inteiro.
```lua
rawlen("")
0
rawlen("abc")
3
rawlen("abc123")
6
rawlen({})
0
rawlen({1,2,4})
3
rawlen({1,2,3, "lua"})
4
rawlen({1,2,3, "lua",{}})
5
```

`rawset(table, index, value)` Define o valor real da `table[index]` como `value`, sem chamar o metamétodo `__newindex`. `table` deve ser uma tabela, `index` qualquer valor diferente de `nil` e `NaN` e `value` qualquer valor de Lua. Esta função modifica e retorna a própria `table`. 
```lua
tab = {10, 20, 30}
print(tab[4]) -- nenhum valor no indice 4
nil

tabela = rawset(tab, 4, "Lua")
print(tab[4])
Lua

print(tabela[4])
Lua

tabela = rawset(tab, 1, "Linguagem")
print(tab[1])
Linguagem

print(tabela[1])
Linguagem
```

`rawequal(v1, v2)` Verifica se `v1` é igual a `v2`, sem chamar o metamétodo `__eq`. Retorna um `boolean`.
```lua
tab = {10,20}
t = {10,20}

tab == t
false

rawequal(tab, t)
false
rawequal(tab[1], t[1])
true

tab[1] == t[1]
true

rawequal("Lua", "Lua")
true

f = function() return "Lua" end
rawequal(f, f)
true

f2 = function() return "Lua" end

f == f2
false

rawequal(f, f2)
false
```

` ipairs (t)` Retorna 3 valores (um `iterator function`, a tabela `t`, e o valor `0`). Itera sobre os pares de chave-valor (1, t[1]), (2, t[2]) até o primeiro valor `nil`.
```lua
--- usa no for generico
t = {10, 20, 30, 40}
for k, v in ipairs(t) do
  print(k, v) 
end
1	10
2	20
3	30
4       40

-- inserindo um valor nil no meio da tabela t
t = {10, 20, nil, 30, 40}
for k, v in ipairs(t) do 
  print(k, v) 
end
1	10
2	20
-- note que iterou até o valor nil ser lido e encerrou.

--[[ se tivermos um elemento no formato chave = valor
ele não é lido, é ignorado.
--]]
t = {10, 20, linguagem = "Lua", 30, 40}
> for k, v in ipairs(t) do print(k, v) end
1	10
2	20
3	30
4	40
```

`pairs(t)`. se `t` tem um *metametodo* `__pairs`, chama-o com `t` como argumento e retorna os três primeiros resultados da chamada. 
Caso contrário, retorna três valores: a função `next`, a tabela `t` e `nil`. `pairs` itera sobre todas os pares chave-valor.

```lua
t = {10, 20, 30}
for k, v in pairs(t) do 
  print(k, v) 
end
1	10
2	20
3       30

t = {10, 20, nil, 30, 40}
> for k, v in pairs(t) do print(k, v) end
1	10
2	20
4	30
5	40
-- com chave-valor no meio da tabela
t = {10, 20, nome = "Lua", 30, 40}
for k, v in pairs(t) do print(k, v) end
1	10
2	20
3	30
4	40
nome	Lua

t = {10, 20, nome = "Lua", 30, 40, autor = "Roberto", lab = "TecGraf"}
for k, v in pairs(t) do print(k, v) end
1	10
2	20
3	30
4	40
autor	Roberto
nome	Lua
lab	TecGraf
```

Outros Recursos
==

Ficaram de fora dessa introdução:

- As bibliotecas: coroutine library, package library, string manipulation, basic UTF-8 support, table manipulation, mathematical functions, input and output, operating system facilities, debug facilities.

Esses recursos serão explicados em outros *posts*, e podem ser conhecidos através do [Lua Reference Manual.](https://www.lua.org/manual/5.3/manual.html#6)


Referências e Links importantes
===

- Site Oficial: [Lua.org](http://www.lua.org/)

- Referência Oficial da Linguagem: [Lua 5.3 Reference Manual](http://www.lua.org/manual/5.3/)

- Livro escrito por um dos autores da linguagem: professor Roberto Ierusalimschy, versão online (Lua 5.0) está desatualizado mas é fundamental [Programming in Lua (first edition)](http://www.lua.org/pil/contents.html)

- Ebook: [Programming in Lua, Fourth Edition Author: Roberto Ierusalimschy](https://store.feistyduck.com/products/programming-in-lua-fourth-edition-ebook)

- Book: [Programming in Lua, Fourth Edition Author: Roberto Ierusalimschy](https://www.amazon.com/exec/obidos/ASIN/8590379868/lua-pilindex-20)

- Site dos usuários de Lua, vários documentos, exemplos, tutoriais, etc [Lua-users](http://lua-users.org/)

- Página do professor Fabio Mascarenhas da UFRJ: Curso de Lua [https://dcc.ufrj.br/~fabiom/lua/](https://dcc.ufrj.br/~fabiom/lua/)