Guia Definitivo de Lua para Iniciantes

Aprenda facilmente programar em Lua.


Guia Definitivo de Lua para Iniciantes

Ultimamente diversas empresas internacionais estão oferecendo vaga no Stack Overflow, remota ou presencial, para programadores C++ que possuem conhecimentos da linguagem de programação Lua, além de diversos softwares e Games estão adotando Lua de maneira muito rápida Então, não deixe essas oportunidades escaparem!

Aqui tem tudo para você iniciar nesse mundo da linguagem de programação Lua!

Vamos lá!

Observação: Esse tutorial é indicado para quem conhece basicamente qualquer linguagem de programação.


Introdução

Lua é uma linguagem de programação interpretada, de script em alto nível, com tipagem dinâmica e multiparadigma, reflexiva e leve, projetada por Tecgraf da PUC-Rio em 1993 para expandir aplicações em geral, de forma extensível (que une partes de um programa feitas em mais de uma linguagem), para prototipagem e para ser embarcada em softwares complexos, como jogos. Assemelha-se com Python, Ruby e Icon, entre outras.

Lua foi criada por um time de desenvolvedores do Tecgraf da PUC-Rio, a princípio, para ser usada em um projeto da Petrobras. Devido à sua eficiência, clareza e facilidade de aprendizado, passou a ser usada em diversos ramos da programação, como no desenvolvimento de jogos (a Blizzard Entertainment, por exemplo, usou a linguagem no jogo World of Warcraft), controle de robôs, processamento de texto, etc. Também é frequentemente usada como uma linguagem de propósito geral.

Lua combina programação procedural com poderosas construções para descrição de dados, baseadas em tabelas associativas e semântica extensível. É tipada dinamicamente, interpretada a partir de bytecodes, e tem gerenciamento automático de memória com coleta de lixo. Essas características fazem de Lua uma linguagem ideal para configuração, automação (scripting) e prototipagem rápida.

Quem usa Lua?

E também:

Jogos que também utilizam Lua:

Exemplos de empresas que desenvolveram jogos usando a linguagem Lua: LucasArts, Croteam, BioWare, Microsoft, Relic Entertainment, Absolute Studios, Monkeystone Games, Blizzard, SNKPlaymore, Facepunch Studios, KOG.

História

Lua foi criada em 1993 por Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes, membros do Computer Graphics Technology Group na PUC-Rio, a Pontifícia Universidade Católica do Rio de Janeiro, no Brasil.[5] Versões de Lua antes da versão 5.0 foram liberadas sob uma licença similar à licença BSD. A partir da versão 5.0, Lua foi licenciada sob a licença MIT.

Alguns de seus parentes mais próximos são o Icon, por sua concepção, e Python, por sua facilidade de utilização por não programadores. Em um artigo publicado no Dr. Dobb’s Journal, os criadores de Lua também afirmam que Lisp e Scheme foram uma grande influência na decisão de desenvolver a tabela como a principal estrutura de dados de Lua. Lua tem sido usada em várias aplicações, tanto comerciais como não comerciais.

O primeiro projeto utilizando a linguagem em jogos foi em 1997 quando a LucasArts a utilizou como linguagem de script no jogo Grim Fandango.[3]

Em 2008 Nasceu uma das engines mais famosas de Lua (Corona SDK)

Em 2009 nasceu o Love2D, uma engine para jogos 2D.

Características

Lua é normalmente descrita como uma linguagem de múltiplos paradigmas, oferecendo um pequeno conjunto de características gerais que podem ser estendidas para encaixar diferentes tipos de problemas, em vez de fornecer uma especificação mais complexa e rígida para combinar com um único paradigma. Lua, por exemplo, não contém apoio explícito à herança, mas permite que ela seja executada com relativa facilidade com metatables. Do mesmo modo, Lua permite que programadores quando implementam nomes, classes, e outras funções, empreguem poderosas técnicas de programação funcional e completos escopos lexicais.

Lua é uma linguagem que suporta apenas um pequeno número de estruturas, tais como dados atômicos, valores booleanos, números (dupla precisão em ponto flutuante por padrão), e strings. As estruturas de dados comuns, tais como matrizes, conjuntos, tabelas, listas, e registros podem ser representados por meio de Lua. Lua não foi construída com suporte para programação orientada a objeto.

Via: https://pt.wikipedia.org/wiki/Lua_(linguagem_de_programação)


Preparando o Ambiente

Para instalar Lua basta usar o gerenciador de pacotes da sua distribuição, exemplo:

Você pode escrever em Lua em qualquer IDE, no entanto, o mais recomendado é o Neovim que incluive veremos como criar um plugin para o Neovim utilizando Lua que possui integração nativa.

Após instalar rode: lua --help a saída será:

lua --help
usage: lua [options] [script [args]].
Available options are:
  -e stat  execute string 'stat'
  -l name  require library 'name'
  -i       enter interactive mode after executing 'script'
  -v       show version information
  --       stop handling options
  -        execute stdin and stop handling options

Exemplos:

Rodar somente o comando lua entra numa subshell, rode os.exit() dentro da subshell para sair.

Parâmetro Uso
-e lua -e 'print("Olá, Lua!")'
-i lua -i script.lua
-v lua -v
Versão
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio

Olá, Mundo!

O mais básico programa.

nvim ola-mundo.lua

print("Olá, Lua!")

E execute: lua ola-mundo.lua ou:

#!/usr/bin/env lua
print("Olá, Lua!")

chmod +x ola-mundo.lua e execute: ./ola-mundo.lua . Você ainda podia substituir o cabeçalho por which lua e adicionar, exemplo: #!/usr/bin/lua

Outras formas de imprimir:

Sem parenteses

print "Olá, sem parênteses, Lua!"

Múltiplas linhas

print [[
Isso pode ser visto
em várias linhas
 inclusive os espaços iniciais
]]

Ou também com parênteses: print([[ ]])


Comentários

Comentários de uma única linha usa-se dois traços(–) pode ser:

-- aqui em cima
print "Luaaaaa" -- aqui ao lado
-- aqui abaixo

Ou em múltiplas linhas

print "Começando o código"
--[[ Comentario
de
multiplas
linhas
]]
print "Terminando o código"

Detalhe: o -- deve ficar colado do [[ do início.


Variáveis

Existem três tipos de variáveis em Lua: variáveis globais, variáveis locais e campos de tabelas. Assume-se que toda variável é uma variável global a menos que ela seja explicitamente declarada como uma variável local.

nome = "Marcos Oliveira"
print(nome)
print("O valor de nome é:", nome) -- saída espaçada com TAB

Criando uma variável local:

local versao = _VERSION
print( versao )

Campos de tabela:

minha_tabela = {
  x = 10,
  y = 20
}

print( minha_tabela.x )
print( minha_tabela.y )

Criando uma tabela vazia e adicionando posteriormente:

tabela = {}
tabela[1] = "Lua"
print( tabela[1])

Concatenação

Para concatenar strings em Lua precisa-se utilizar duas vezes o ponto: .. , exemplo:

ola = "Olá"
mundo = "Mundo"
print( ola .. ", " .. mundo .. "!" )

Saída: Olá, Mundo! .

Podemos declarar múltiplas variáveis e imprimir assim:

nome,sobrenome = "Marcos","Olivera"
print(nome .. " " .. sobrenome)

Constantes

Lua antes da versão 5.4 não oferecia suporte a constantes automaticamente, mas você pode adicionar uma tabela e tornando a tabela somente leitura usando metatabela(veremos mais à frente isso). Mas a partir da 5.4 use assim:

local minha_var <const> = 42
print( minha_var )

Rode: lua5.4 constantes.lua

Se tentar redefinir, exemplo:

minha_var = 24

Obterá o erro: lua5.4: sandbox.lua:3: attempt to assign to const variable 'minha_var'


Arrays ou Matrizes

Matrizes são arranjos ordenados de objetos, que podem ser uma matriz unidimensional contendo uma coleção de linhas ou uma matriz multidimensional contendo várias linhas e colunas.

Em Lua, os arrays são implementados usando tabelas de indexação com inteiros. O tamanho de um array não é fixo e pode crescer com base em nossos requisitos, sujeito a restrições de memória.

Em Lua o array/matriz começa do 1, se tentar imprimir o 0(zero) a saída será nil

Matriz unidimensional

Uma matriz unidimensional pode ser representada usando uma estrutura de tabela simples e pode ser inicializada como é mostrado abaixo.

meu_array = {"Lua", "C++", "JavaScript", "C", "Bash", "Rust", "PHP"}
print( meu_array[1]) -- Lua

Tipos de Dados

A tipagem dos dados em Lua é dinâmica, mas caso você queira obter o tipo do dado basta, exemplo:

print( type("Qual o tipo desse dado?") ) -- string
print( type(936) ) -- number
print( type( true ) ) -- boolean
print( type( print ) ) -- function
print( type( os ) ) -- table
print( type( nil ) ) -- nil

nome = "Marcos Oliveira"
print( type( type ) ) -- function
print( type( 9.36 ) ) -- num
print( type( nome ) ) -- string

Além desse também existem os tipos: userdata e thread .


Operadores

Lua utiliza quase todos os operadores que outras linguagens de programação utilizam, exemplos:

operador operador operador operador
+ - * /
% ^ == ~=
> < >= <=
and or not #

Além do .. que nós já vimos que serve para concatenação.

Exemplos:

-- soma
print("2 + 2:")
print(2 + 2) -- 4

-- subtração
print("2 - 2:")
print(2 - 2) -- 0

-- multiplicação
print("2 * 2:")
print(2 * 2) -- 4

-- divisão
print("2 / 2:")
print(2 / 2) -- 1

-- resto da divisão(módulo)
print("2 % 2:")
print(2 % 2) -- 0

Os outros veremos mais à frente!


Condições

Assim como as demais linguagens de programção, Lua também dispões de condições, lógico(o recurso mais utilizado em qualquer linguagem de programação).

Note o uso das palavras: then e end

Para usar o if, exemplo:

numero = 10

if( numero == 10 ) then
  print("O número é igual a DEZ")
end

Para usar o else

numero = 8

if( numero == 10 ) then
  print("O número é igual a DEZ")
else
  print("O número é diferente de DEZ")
end

Para usar o elseif

numero = 8

if( numero == 10 ) then
  print("O número é igual a DEZ")
elseif( numero == 8 ) then
  print("O número é OITO")
else
  print("O número é DIFERENTE de DEZ e de OITO")
end

Loops

Para executarmos uma ação em determinadas vezes utilizamos loops, em Lua há 3 tipos de loops: while, for e repeat until vamos ver como utilizá-los:

Note o uso das palavras reservadas: do e end

Loop while

numero = 1

while( numero < 4 ) do
  print("Imprimindo " .. numero .. "º vez!")
  numero = numero + 1
end

Loop for

Exemplos variados.

-- valor crescente
for i = 1,4 do
 print("Imprimindo "..i.."º vez!") 
end
-- valor decrescente
for i = 4,1,-1 do
 print("Imprimindo "..i.."º vez!") 
end

Loop repeat until

numero = 4 -- começa do número 4
repeat
   print("O valor de 'numero' é: "..numero)
   numero = numero + 1
until( numero > 8 ) -- até o número 8

Utilizando o break

numero = 4 -- começa do número 4
repeat
  print("O valor de 'numero' é: "..numero)
  if( numero == 6 ) then -- se for igual à 6 pára o loop
    break
  end
  numero = numero + 1
until( numero > 8 ) -- até o número 8

Funções

Funções são importantes para reaproveitamento de código, vamos ver algumas formas de usar em Lua.

Função básica:

function ola_mundo()
  print("Olá Lua via função!")
end

ola_mundo() -- chama a função

Passando parâmetros:

function soma( x, y)
  print(x.." + "..y.." = "..x + y)
end

soma( 3, 9)

Utilizando assinatura:

saida = function(flag)
  print("O resultado é: "..flag)
end

function soma( x, y, callback)
  resultado = x + y
  callback(resultado)
end

soma( 3, 9, saida)

Função com argumento variável:

Observe o uso da função nativa ipairs que é um iterador(veremos mais detalhes posteriormente)

function qtd_params(...)
  local qtd = 0;
  parametros = {...}
  for i,v in ipairs(parametros) do
    qtd = qtd + 1
  end
  return qtd
end

print([[A quantidade de parâmetros passados
para a função qtd_params(...) é: ]] .. qtd_params(8,4,11,2,17))

Nesse caso passamos 5 parâmetros para a função.

Imprimindo todos os parâmetros passados com argumento variável:

function list_params(...)
  local qtd = 0;
  parametros = {...}
  for i,v in ipairs(parametros) do
    qtd = qtd + 1
  end

  for j = 1,qtd do
    print("O "..j.."º parâmetro é: "..parametros[j])
  end
end

list_params("Marcos", "Oliveira", "Terminal", "Root")

Trabalhando com strings

str = [[Lua é muito bacana!]]
print(str)
str = "Lua é muito bacana!"
amarelo = "\027[33m"
desliga = "\027[m"
print(amarelo..str..desliga)
str = "Lua é muito bacana!"

-- do 30 ao 37(8 cores)
-- mas tem mais: tente do 0 até 106
for i = 30,37 do
  if( i == 30) then
    -- se seu terminal for a cor do fundo
    -- não aparecerá o fundo
    print("\027[90m"..str.."\027[m")
  else
    print("\027["..i.."m"..str.."\027[m")
  end
end
str = "Lua é muito bacana!"
print( string.upper( str ) )

Perceba que as palavras acentuadas não alteram. Veremos como alterar isso quando falarmos sobre inclusão de bibiliotecas.

Para minúscula

str = "Lua é muito bacana!"
print( string.lower( str ) )
str = "Perl é muito bacana!"
str = string.gsub(str,"Perl","Lua")
print(str)
str = "❤"
print( string.format("Eu %s Lua!",str))
dia,mes,ano = 26,08,2021
print( string.format("%d/%02d/%d",dia,mes,ano))

Para o mês com zero: %02d.

print( string.format("%.4f",3.1415))
str = "A linguagem de programação Lua é muito legal"

if( string.find(str,"muito") ) then
  print("Encontrada a palavra 'muito'")
else
  print("NÃO foi encontrada a palavra 'muito'")
end

if( string.find(str,"tchau") ) then
  print("Encontrada a palavra 'tchau'")
else
  print("NÃO foi encontrada a palavra 'tchau'")
end
str = "Uauu! A Lua!"
print( string.reverse(str))
str = "Lua"
print( string.len(str))
str = "Lua Linguagem de Programação"
print( string.sub(str,0,3) )
str = "Lua Linguagem de Programação"
print( string.sub(str, string.len(str) - 12, string.len(str) ) )

Ou

str = "Lua Linguagem de Programação"
print( string.sub(str, 18, 30 ) )
str = "Lua "
print( string.rep(str,4))
print( string.byte("Lua")) -- primeiro caractere
print( string.byte("Lua",2)) -- segundo caractere
print( string.byte("Lua",-1)) -- último caractere
print( string.byte("Lua",-2)) -- penúltimo caractere
print( string.char(97)) -- primeiro caractere

Trabalhando com Tabelas

As tabelas são a única estrutura de dados disponível em Lua que nos ajuda a criar diferentes tipos, como arrays e dicionários. Lua usa matrizes associativas e que podem ser indexadas não apenas com números, mas também com strings, exceto nil. As tabelas não têm tamanho fixo e podem crescer de acordo com nossa necessidade.

Lua usa tabelas em todas as representações, incluindo a representação de pacotes. Quando acessamos um método string.format, significa que estamos acessando a função de formatação disponível no pacote string.

As tabelas são chamadas de objetos e não são valores nem variáveis. Lua usa uma expressão construtora {} para criar uma tabela vazia. É preciso saber que não existe uma relação fixa entre uma variável que contém a referência da tabela e a própria tabela.

Leia os comentários no código para um maior entendimento:

tabela = {"Lua", "C++", "JavaScript", "C"}

-- imprime tudo junto
print("Imprimido a tabela: " .. table.concat(tabela))

-- imprime com espaçamento
print("Imprimido a tabela: " .. table.concat(tabela," "))

-- imprime do segundo ao terceiro elemento
print("Imprimido a tabela: " .. table.concat(tabela," ",2,3))

-- removendo o último índice da tabela:
table.remove( tabela)
print( table.concat( tabela,", " ) )

-- removendo o 3º índice(JavaScript) da tabela:
table.remove( tabela, 3)
print( table.concat( tabela,", " ) )

-- insere um índice(Rust) na última posição
table.insert(tabela, "Rust" )
print( table.concat( tabela," " ) )

-- insere um índice(PHP) na 1º posição
table.insert(tabela, 1, "PHP" )
print( table.concat( tabela," " ) )

-- informa a quantidade de índices da tabela
print("A 'tabela' tem: "..table.maxn(tabela) .. " índices")

Também há as funções: sort, foreach, foreachi e getn. Saiba mais aqui.


Módulos

O módulo é como uma biblioteca que pode ser carregada usando require e tem um único nome global contendo o código a ser utilizado.

Exemplo: Usando uma função que está no arquivo meu_modulo.lua do programa programa.lua:

meu_modulo.lua

function minha_funcao( param )
  print("Você passou o parâmetro: " .. param)
end

programa.lua

require "meu_modulo"

minha_funcao("Olá, módulo!")

Outra forma de usar e instanciar o módulo:

meu_modulo.lua

local mf = {}

function mf.minha_funcao( param )
  print("Você passou o parâmetro: " .. param)
end

return mf

programa.lua

mf = require ("meu_modulo")
mf.minha_funcao("Lua é demais!")

Trabalhando com a Shell

Vamos utilizar a biblioteca nativa os

home = os.getenv("HOME")
pwd = os.getenv("PWD")
editor = os.getenv("EDITOR")

print("Seu diretório pessoal é: " .. home)
print("Você está no diretório: " .. pwd)
print("Seu editor padrão é: " .. editor)
os.execute("echo 'Olá, Shell via Lua!'")
os.execute("uptime")
os.execute("touch file.txt")
os.execute("ls")
os.remove("file.txt")

Saiba mais em: https://www.lua.org/pil/22.1.html


Passando Parâmetros via linha de comando

Para isso usa-se a palavra reservada: arg. Veja os exemplos abaixo:

print( "O nome do arquivo é: " .. arg[0])

print([[Quantidade de argumentos
via linha de comando: ]] .. #arg)

if( #arg > 0 ) then
  for i = 1,#arg do
    print("Argumento "..i.." é "..arg[i])
  end
end

print("O comando é: " .. arg[-1])

MetaTabelas

Uma metatabela é uma tabela que ajuda a modificar o comportamento de uma tabela à qual está anexada com a ajuda de um conjunto de chaves e métodos meta relacionados. Esses metamétodos são funcionalidades Lua poderosas que habilitam recursos como -

Existem dois métodos importantes que são usados no tratamento de meta-tabelas, que incluem -

Vejamos primeiro como definir uma tabela como metatabela de outra. É mostrado abaixo.

minha_tabela = {}
minha_meta_tabela = {}
setmetatable( minha_tabela , minha_meta_tabela )

Ou somente:

minha_tabela = setmetatable({}, {})

Utilizando __index

Um exemplo simples de metatabela para pesquisar a metatabela quando não está disponível na tabela é mostrado abaixo.

minha_tabela = setmetatable({chave1 = "valor1"}, {
   __index = function(minha_tabela, key)

      if key == "chave2" then
         return "Valordametatabela"
      else
         return minha_tabela[key]
      end
   end
})

print(minha_tabela.chave1,minha_tabela.chave2)

Saída: valor1 Valordametatabela

Resumindo o código acima:

minha_tabela = setmetatable({chave1 = "valor1"},
   { __index = { chave2 = "VALOR DA META TABELA" } })
print(minha_tabela.chave1,minha_tabela.chave2)

Se um índice não existir e você deseja adicionar quando for chamado e não existir você pode usar __newindex e criar um método/função para isso.

Mais informações aqui.


LuaJIT

LuaJIT é um Compilador Just-In-Time (JIT) para a linguagem de programação Lua. Seu site oficial é: https://luajit.org/ .

JIT é uma tecnologia que compila um programa em tempo de execução.

A implementação LuaJIT parece superar todas as outras linguagens dinâmicas do JIT (V8, Tracemonkey, PLT Scheme, Erlang HIPE) por um ordem de magnitude .

Para instalar o LuaJIT use o gerenciador de pacotes do seu sistema, exemplos:

sudo emerge luajit # Gentoo, Funtoo e similares
sudo apt install luajit # Debian, Ubuntu e similares
sudo pacman -S luajit # Arch, Manjaro e similares
sudo dnf install luajit # Fedora, Red Hat e similares
# ...

Para utilizá-lo, em vez de usar o comando lua, use luajit, exemplo:

luajit meuprograma.lua

LuaJIT fornece uma desempenho superior ao interpretador Lua.

Como acontece com todo sistema de alto desempenho, a resposta no final se resume a duas coisas: algoritmos e engenharia. LuaJIT usa técnicas de compilação avançadas e também tem uma implementação de engenharia muito precisa. Por exemplo, quando as sofisticadas técnicas de compilação não conseguem lidar com um trecho de código, LuaJIT recorre a um interpretador muito rápido escrito em assembly x86.

LuaJIT ganha pontos duplos no aspecto de engenharia, porque não apenas LuaJIT em si é bem projetado, mas a própria linguagem Lua tem um design mais simples e mais coerente do que Python e JavaScript. Isso torna (marginalmente) mais fácil para uma implementação fornecer um desempenho consistentemente bom.


LuaRocks

LuaRocks é um gerenciador de pacotes para a linguagem de programação Lua, similar aos gerenciadores de pacotes de outras linguagens como: npm(JavaScript), composer(PHP), gem(Ruby), pip(Python) e entre outros.

Seu site oficial é: https://luarocks.org/

Fornece um formato padrão para distribuição de módulos Lua (em um formato independente chamado “rock”), uma ferramenta projetada para gerenciar facilmente a instalação de rocks e um servidor para distribuí-los . Embora não esteja incluído na distribuição Lua, é chamado de “gerenciador de pacotes de fato para módulos Lua contribuídos pela comunidade”.

Para instalá-lo use também o gerenciador de pacotes do seu sistema, exemplos:

sudo emerge luarocks # Gentoo, Funtoo e similares
sudo apt install luarocks # Debian, Ubuntu e similares
sudo pacman -S luarocks # Arch, Manjaro e similares
sudo dnf install luarocks # Fedora, Red Hat e similares
# ...

Para utilizá-lo use o comando luarocks --help .


Espero que vocês tenham gostado dessa pequena introdução à essa belíssima Linguagem de Programação que é Lua.

Acompanhe a nossa #hashtag: https://terminalroot.com.br/tags#lua para mais tutoriais e dicas de Lua e também de Neovim que usa Lua como principal fonte de configuração. Futuramente pode ser que iremos expandir esse tutorial, então não esqueça de voltar aqui sempre que possível!

Abraços!


Quais seus assuntos preferidos?


Cursos Udemy Promoção C++ Linguagem C Filmes Livros Hardware GNU Windows Python Node.js Vim Artigos Git Feed MySQL HTML CSS JavaScript Jekyll Notícias English Awk Sed Regex Blog GitHub GitLab Desenvolvimento Web Vue.js Games PHP macOS Apache Redes GIMP MarkDown Docker jQuery MongoDB PostGreSQL Comandos Ruby Atom OpenBSD Shell Script Bash Gentoo FreeBSD

Receba as novidades no seu e-mail!

Após cadastro e confirmação do e-mail, enviaremos semanalmente resumos e também sempre que houver novidades por aqui para que você mantenha-se atualizado!