Aprenda Lua em 15 minutos

-- Dois hifens começam um comentário de uma linha.

--[[
Adicionando dois "[" e "]" cria um
comentário de múltiplas linhas
--]]

----------------------------------------------------
-- 1. Variáveis e controle de fluxo.
----------------------------------------------------

num = 42 -- Todos os números são Double.
-- Não se espante, 64-bit Doubles têm 52 bits para armazenar valores inteiros exatos;
-- precisão da máquina não é um problema para inteiros que precisam de menos de 52 bits.

s = 'aspas simples' -- Strings imutáveis, como Python
t = "aspas duplas também funcionam"
u = [[ Chaves duplas
começam e terminam
uma string de múltiplas linhas. ]]
t = nil -- Indefine t; Lua tem coleta de lixo.

-- Blocos são denotados com palavras-chave como do/end:
while num < 50 do
num = num + 1 -- Não há os operadores ++ ou +=.
end

-- Condições If
if num > 40 then
print('acima de 40')
elseif s ~= 'aspas simples' then -- ~= significa diferente (não igual).
-- Igualdade é ==, como em Python; ok para strings.
io.write('não é maior que 40\n') -- Padrão de saída (stdout).
else
-- Variáveis são globais por padrão.
istoEhGlobal = 5 -- Camel Case é comum.

-- Como fazer uma variável local
local linha = io.read() -- Lê a próxima linha de entrada (stdin).

-- Concatenação de string usa o operador ..
print('O inverno está chegando, ' .. linha)
end

-- Variáveis indefinidas retornam nil.
-- Isto não é um erro:
nada = valorDesconhecido -- Agora nada = nil.

valorBooleano = false

-- Apenas nil e false são falsos; 0 e "" são true (verdadeiros)!
if not valorBooleano then print('falso') end

-- 'or' e 'and' funcionam em sistema de short-circuiting.
-- É semelhante ao operador a?b:c em C/JS:
resposta = valorBooleano and 'sim' or 'não' --> não

minhaSoma = 0
for i = 1, 100 do -- O alcance/raio/intervalo inclui ambos os fins [1-100]
minhaSoma = minhaSoma + 1
end

-- Use "100, 1, -1" como um alcance/raio/intervalo em ordem decrescente:
suaSoma = 0
for j = 100, 1, -1 do suaSoma = suaSoma + j end

-- Em geral, o alcance/raio/intervalo é Começo, Final[, Etapa].

-- Outra construção de loop:
repeat
print("Para o alto e avante")
num = num - 1
until num == 0

----------------------------------------------------
-- 2. Funções.
----------------------------------------------------

function Fibonacci(n)
if n < 2 then return 1 end
return Fibonacci(n - 2) + Fibonacci(n - 1)
end

-- Funções anônimas e "Closures" funcionam:
function adicionador(x)
-- A função retornada é criada quando adicionar é chamado
-- e lembra o valor de x
return function(y) return x + y end
end
a1 = adicionador(9)
a2 = adicionador(36)
print(a1(16)) --> 25
print(a2(64)) --> 100

-- Todos os retornos, chamadas de função e atribuições funcionam
-- como listas que talvez possam estar incompatíveis em comprimento/tamanho.
-- Variáveis incompatíveis são nil;
-- Valores incompatíveis são descartadas.

x, y, z = 1, 2, 3, 4
-- Agora x = 1, y = 2, z = 3, e 4 foi jogado fora.

function barra(a, b, c)
print(a, b, c)
return 4, 8, 16, 23, 42
end

x, y = barra("teste") --> Imprime "teste nil nil"
-- Agora x = 4, y = 8, valores de 15 até 42 são descartados.

-- Funções são primeira classe, podem ser locais ou globais.
-- Ambas são as mesmas:
function f(x) return x * x end
f = function(x) return x * x end

-- E também:
local function g(x) return math.sin(x) end
local g; g = function(x) return math.sin(x) end
-- A declaração 'local g' cria uma referência de/em g.

-- A propósito, funções trigonométricas trabalham em radiano.

-- Chamadas com um parâmetro não precisam de parênteses:
print 'hello' -- Funciona

----------------------------------------------------
-- 3. Tabelas.
----------------------------------------------------

-- Tabelas = Única estrutura de dados compostos em Lua; São arrays associativas.
-- Similar às arrays de PHP ou objetos de JS.
-- São como dicts (dicionários) em Python que podem ser usados, também, como listas.

-- Usando tabelas como dicionários / mapas:

-- Têm chaves de tipo string como padrão:
t = {chave1 = 'valor1', chave2 = false}

-- Chaves de tipo string usam notação com um ponto '.'
print(t.chave1) -- Imprime 'valor1'.
t.novaChave = {} -- Adiciona um novo par de chave/valor
t.chave2 = nil -- Remove chave2 da tabela.

-- Notação literal para qualquer valor não nulo como chave:
u = {["@!#"] = 'Brasil', [{}] = 1729, [1.41] = 'Órion'}
print(u[1.41]) -- Imprime 'Órion'.

-- Correspondência de chave é basicamente de valor para números e strings, mas por identidade por tabelas.
a = u["@!#"] -- Agora a = 'Brasil'
b = u[{}] -- Espera-se 1729, mas é nil:
-- b = nil porque a pesquisa falhou.
-- Falhou porque a chave usada não é o mesmo objeto que a usada para armazenar o valor original.
-- Então strings e números são chaves mais portáveis.

-- A chamada de uma função que contém apenas um parâmetro, tal sendo uma tabela, não precisa de parênteses:
function h(x) print(x.chave1) end
h{chave1 = 'Teste1234'} -- Imprime 'Teste1234'.

for chave, valor in pairs(u) do -- Iteração/Repetição de tabela
print(chave, valor)
end

-- _G é uma tabela especial que armazena todas as variáveis globais.
print(_G['_G'] == _G) -- Imprime 'true'.

-- Usando tabelas como listas / arrays:

-- Têm chaves de tipo inteiro como padrão:
v = {'valor1', 'valor2', 1.244, 'internet'}
for i = 1, #v do -- #v é o tamanho de v
print(v[i]) -- Índices começam em 1, não 0.
end
-- Uma 'lista' não é um tipo real. v é apenas uma tabela com
-- consecutivos índices inteiros, tratados como uma lista.

----------------------------------------------------
-- 3.1 Metatabelas e Metamétodos.
----------------------------------------------------

-- Uma tabela pode ter uma metatabela que fornece um comportamento de "operador de sobrecarga".
-- Depois veremos como metatabelas suportam comportamentos como os prototipados em JS.

f1 = {a = 1, b = 2} -- Representa a fração a/b .
f2 = {a = 2, b = 3}

-- Isso daria errado:
-- s = f1 + f2

metaFracao = {}
function metaFracao.__add(f1, f2)
soma = {}
soma.b = f1.b * f2.b
soma.a = f1.a * f2.b + f2.a * f1.b
return soma
end

setmetatable(f1, metaFracao)
setmetatable(f2, metaFracao)

s = f1 + f2 -- Chama __add(f1, f2) na metatabela de f1

-- f1, f2 não têm chaves para suas metatabelas, ao contrário dos protótipos em JS, então
-- podem ser recuperadas usando getmetatable(f1). A metatabela é uma tabela normal com
-- chaves das quais Lua reconhece, como __add.

-- Mas a próxima linha dá erro, uma vez que s não tem metatabela:
-- t = s + s
-- Padrões de "classes" dadas abaixo consertam isso.

-- Um __index numa metatabela sobrecarrega pesquisas com ponto '.':
favoritos = {animal = "Galinha Galinácea", comida = "Nachos"}
meusFavoritos = {comida = "Batata Frita"}
setmetatable(meusFavoritos,{__index = favoritos})
comidoPor = meusFavoritos.animal -- Funciona!

-- Pesquisas diretas com ponto '.' em tabelas que falharem tentarão novamente usando
-- o valor __index da metatabela e seus recursos.

-- Um valor __index pode ser também uma função, function(tabela, chave) para pesquisas mais customizadas.

-- Valores de __index, add, ... são chamados de metamétodos.
-- Todos os metamétodos estão listados abaixo, onde a é uma tabela com o metamétodo.

-- __add(a, b) --> para a + b
-- __sub(a, b) --> para a - b
-- __mul(a, b) --> para a * b
-- __div(a, b) --> para a / b
-- __mod(a, b) --> para a % b
-- __pow(a, b) --> para a ^ b
-- __unm(a) --> para -a
-- __concat(a, b) --> para a .. b
-- __len(a) --> para #a
-- __eq(a, b) --> para a == b
-- __lt(a, b) --> para a < b
-- __le(a, b) --> para a <= b
-- __index(a, b) --> Função ou tabela --> para a.b
-- __newindex(a, b, c) --> para a.b = c
-- __call(a, ...) --> para a(...)

--------------------------------------------------------
-- 3.2 Tabelas como classes e herança.
--------------------------------------------------------

-- Classes não vem embutidas; há formas diferentes de criá-las
-- usando tabelas e metatabelas.

-- Explicação abaixo do código.

planeta = {} -- 1.

function planeta:new(habitavel, celcius) -- 2.
novoObjeto = {vida = habitavel, temperatura = celcius} -- 3.
self.__index = self -- 4.
return setmetatable(novoObjeto, self) -- 5.
end

function planeta:verificarVida() -- 6.
print((not self.vida and "não " or "") .. "sou habitável! ")
end

marte = planeta:new(true, 30) -- 7.
marte:verificarVida() -- 8.

--[[ 1. planeta agirá como uma classe, mas é uma tabela.
2. function nomedatabela:funcao(...) é o mesmo que function nomedatabela.funcao(self, ...)
o : adiciona um primeiro argumento chamado self.
Leia 7 & 8 para ver como self pega seu valor.
3. novoObjeto será uma instância da classe planeta.
4. self = a classe sendo instanciada. Geralmente self = planeta, mas a herança pode alterar isso.
novoObjeto obtém as funções de self quando definimos as metatabelas de novoObjeto
e o __index de self em self.
5. setmetatable retorna seu primeiro argumento.
6. O : funciona como em 2, mas desta vez self será uma instância ao invés de uma classe.
7. O mesmo que planeta.new(planeta), então self = planeta em new().
8. O mesmo que marte.verificarVida(marte); self = marte. ]]

----------------------------------------------------

-- Exemplo de herança:

estrela = planeta:new(false, 1000) -- 1.

function estrela:calor()
s = self.temperatura .. "°C" -- 2.
print("Minha temperatura é de " .. s)
end

sirius = estrela:new() -- 3.
sirius:calor() -- 4.

--[[ 1. estrela obtém os métodos e variáveis de planeta.
2. self tem uma chave 'temperatura', vinda de new(), veja 3.
3. o mesmo que estrela.new(estrela), e convertido para
planeta.new(estrela) já que estrela não tem nova chave, mas
tem __index = planeta em sua metatabela.
Resultado: a metatabela de sirius é estrela, e estrela.__index = estrela,
então sirius.chave = sirius.chave, estrela.chave, planeta.chave, qualquer tabela
é a primeira com a chave dada.
4. A chave 'calor' se encontra em estrela; é o mesmo que estrela.calor(sirius). ]]

-- Se necessário, uma subclasse de new() é como a base:
function estrela:new()
novoObjeto = {}
-- configure novoObjeto
self.__index = self
return setmetatable(novoObjeto, self)
end

--[[
Criado pelo usuário do Github Tylerneylon (veja oficial https://gist.github.com/tylerneylon/5853042)
Traduzido por Bolodefchoco e publicado por Rikkeshang.

Para quem quer usar, assim como eu, o LUA para desenvolver Dialplan no Asterisk, temos um grupo no telegram, mas é somente para discutir sobre LUA em Dialplan do Asterisk, por favor respeite. Segue o link: https://t.me/asteriskluabr

Divirta-se com Lua (:.
]]
Share:

0 comentários:

Aviso importante!

Não realizamos upload dos ficheiros, apenas reportamos os links que encontramos na própria Internet. Assim, toda e qualquer responsabilidade não caberá ao administrador deste blog. Este blog não tem como objetivo reproduzir as obras, apenas divulgar o que foi encontrado na Internet. Os filmes aqui informados são de cunho científico assim como as séries, as quais são produzidas para exibição em TV aberta. Uma vez que a série não tenha sido ripada de um DVD, ou seja, a mesma foi gravada do sinal de TV aberta com o respectivo selo da emissora. Não é caracterizado crime, pois a mesma foi produzida para exibição pública. Será crime quando for realizado venda desta série ou filme. Quem efetuar download de qualquer ficheiro deste blog, que não tenha seu conteúdo de base Open Source (Código Aberto), ou FOSS (Free Open Source Software), deverá estar ciente que terá 24 horas para eliminar os ficheiros que baixou. Após assistir e gostar do filme ou série, adquira o original via lojas especializadas. Se algo contido no blog lhe causa dano ou prejuízo, entre em contato que iremos retirar o ficheiro ou post o mais rápido possível. Se encontrou algum post que considere de sua autoria, favor enviar e-mail para suporte@delphini.com.br informando o post e comprovando sua veracidade. Muito obrigado a todos que fizeram deste blog um sucesso.

Creative CommonsEsta obra está licenciada sob uma Licença Creative Commons. Você pode copiar, distribuir, exibir, executar, desde que seja dado crédito ao autor original (Citando nome do autor, data, local e link de onde tirou o texto). Você não pode fazer uso comercial desta obra.Você não pode criar obras derivadas.

Nossos 10 Posts Mais Populares