Lua - Guia Rápido

Lua é uma linguagem de programação extensível e leve escrita em C. Ela começou como um projeto interno em 1993 por Roberto Ierusalimschy, Luiz Henrique de Figueiredo e Waldemar Celes.

Ele foi projetado desde o início para ser um software que pode ser integrado ao código escrito em C e outras linguagens convencionais. Essa integração traz muitos benefícios. Ele não tenta fazer o que C já pode fazer, mas visa oferecer o que C não é bom: uma boa distância do hardware, estruturas dinâmicas, sem redundâncias, facilidade de teste e depuração. Para isso, Lua possui um ambiente seguro, gerenciamento automático de memória e boas facilidades para lidar com strings e outros tipos de dados com tamanho dinâmico.

Características

Lua oferece um conjunto de recursos exclusivos que a diferenciam de outras linguagens. Isso inclui -

  • Extensible
  • Simple
  • Efficient
  • Portable
  • Livre e aberto

Código de exemplo

print("Hello World!")

Como Lua é implementada?

Lua consiste em duas partes - a parte do interpretador Lua e o sistema de software em funcionamento. O sistema de software em funcionamento é um aplicativo de computador real que pode interpretar programas escritos na linguagem de programação Lua. O interpretador Lua é escrito em ANSI C, portanto, é altamente portátil e pode ser executado em um vasto espectro de dispositivos, de servidores de rede de ponta a pequenos dispositivos.

Tanto a linguagem de Lua quanto seu interpretador são maduros, pequenos e rápidos. Ele evoluiu de outras linguagens de programação e dos principais padrões de software. O tamanho pequeno permite que ele seja executado em dispositivos pequenos com pouca memória.

Aprendendo Lua

O ponto mais importante ao aprender Lua é focar nos conceitos sem se perder em seus detalhes técnicos.

O objetivo de aprender uma linguagem de programação é se tornar um programador melhor; isto é, para se tornar mais eficaz no projeto e implementação de novos sistemas e na manutenção dos antigos.

Alguns usos da lua

  • Programação de jogos

  • Script em aplicativos autônomos

  • Scripting na Web

  • Extensões e add-ons para bancos de dados como MySQL Proxy e MySQL WorkBench

  • Sistemas de segurança como Sistema de Detecção de Intrusão.

Configuração de ambiente local

Se você ainda deseja configurar seu ambiente para a linguagem de programação Lua, precisa dos seguintes softwares disponíveis em seu computador - (a) Editor de Texto, (b) O Interpretador Lua e (c) Compilador Lua.

Editor de texto

Você precisa de um editor de texto para digitar seu programa. Os exemplos de alguns editores incluem o bloco de notas do Windows, o comando Editar sistema operacional, Brief, Epsilon, EMACS e vim ou vi.

O nome e a versão do editor de texto podem variar em diferentes sistemas operacionais. Por exemplo, o Bloco de notas será usado no Windows e o vim ou vi pode ser usado no Windows, bem como no Linux ou UNIX.

Os arquivos que você cria com o seu editor são chamados de arquivos-fonte e esses arquivos contêm o código-fonte do programa. Os arquivos-fonte para programas Lua são normalmente nomeados com a extensão".lua".

O Lua Intérprete

É apenas um pequeno programa que permite digitar comandos Lua e executá-los imediatamente. Ele interrompe a execução de um arquivo Lua caso encontre um erro, ao contrário de um compilador que executa completamente.

O Compilador Lua

Quando estendemos Lua para outras linguagens / aplicações, precisamos de um Kit de Desenvolvimento de Software com um compilador compatível com a Interface de Programa de Aplicação Lua.

Instalação em Windows

Existe um IDE separado chamado "SciTE" desenvolvido para o ambiente do Windows, que pode ser baixado de https://code.google.com/p/luaforwindows/ seção de download.

Execute o executável baixado para instalar o Lua IDE.

Por ser um IDE, você pode criar e construir o código Lua usando o mesmo.

No caso, você está interessado em instalar Lua em modo de linha de comando, você precisa instalar o MinGW ou Cygwin e então compilar e instalar Lua no Windows.

Instalação em Linux

Para baixar e construir Lua, use o seguinte comando -

$ 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

Para instalar em outras plataformas como aix, ansi, bsd, linux genérico, mingw, posix, solaris, substituindo o Linux em make Linux, teste com o nome da plataforma correspondente.

Temos um helloWorld.lua, em Lua da seguinte forma -

print("Hello World!")

Agora, podemos construir e executar um arquivo Lua, digamos helloWorld.lua, mudando para a pasta que contém o arquivo usando cd e, em seguida, usando o seguinte comando -

$ lua helloWorld

Podemos ver a seguinte saída.

Hello World!

Instalação em Mac OS X

Para construir / testar Lua no Mac OS X, use o seguinte comando -

$ 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

Em certos casos, você pode não ter instalado o Xcode e as ferramentas de linha de comando. Nesses casos, você não poderá usar o comando make. Instale o Xcode da loja de aplicativos mac. Em seguida, vá para Preferências do Xcode, mude para Downloads e instale o componente chamado "Ferramentas de linha de comando". Assim que o processo for concluído, o comando make estará disponível para você.

Não é obrigatório executar a instrução "make macosx test". Mesmo sem executar este comando, você ainda pode usar Lua no Mac OS X.

Temos um helloWorld.lua, em Lua, como segue -

print("Hello World!")

Agora, podemos construir e executar um arquivo Lua, digamos helloWorld.lua, mudando para a pasta que contém o arquivo usando cd e, em seguida, usando o seguinte comando -

$ lua helloWorld

Podemos ver a seguinte saída -

Hello World!

Lua IDE

Conforme mencionado anteriormente, para o Windows SciTE, Lua IDE é o IDE padrão fornecido pela equipe de criadores de Lua. O IDE alternativo disponível é do ZeroBrane Studio, que está disponível em várias plataformas como Windows, Mac e Linux.

Existem também plugins para o eclipse que permitem o desenvolvimento de Lua. Usar IDE torna mais fácil o desenvolvimento com recursos como autocompletar código e é altamente recomendado. O IDE também fornece programação em modo interativo semelhante à versão de linha de comando de Lua.

Vamos começar a criar nosso primeiro programa Lua!

Primeiro Programa Lua

Programação de modo interativo

Lua fornece um modo denominado modo interativo. Neste modo, você pode digitar instruções uma após a outra e obter resultados instantâneos. Isso pode ser invocado no shell usando o lua -i ou apenas o comando lua. Depois de digitar isso, pressione Enter e o modo interativo será iniciado conforme mostrado abaixo.

$ lua -i $ Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
quit to end; cd, dir and edit also available

Você pode imprimir algo usando a seguinte declaração -

print("test")

Depois de pressionar enter, você obterá o seguinte resultado -

test

Modo de programação padrão

Invocar o interpretador com um parâmetro de nome de arquivo Lua inicia a execução do arquivo e continua até que o script seja concluído. Quando o script é concluído, o intérprete não está mais ativo.

Vamos escrever um programa Lua simples. Todos os arquivos Lua terão extensão .lua. Portanto, coloque o seguinte código-fonte em um arquivo test.lua.

print("test")

Supondo que o ambiente lua esteja configurado corretamente, vamos executar o programa usando o seguinte código -

$ lua test.lua

Obteremos a seguinte saída -

test

Vamos tentar outra maneira de executar um programa Lua. Abaixo está o arquivo test.lua modificado -

#!/usr/local/bin/lua

print("test")

Aqui, assumimos que você tem um interpretador Lua disponível em seu diretório / usr / local / bin. A primeira linha é ignorada pelo intérprete, se começar com o sinal #. Agora, tente executar este programa da seguinte maneira -

$ chmod a+rx test.lua
$./test.lua

Obteremos a seguinte saída.

test

Vamos agora ver a estrutura básica do programa Lua, de forma que seja fácil para você entender os blocos de construção básicos da linguagem de programação Lua.

Tokens em Lua

Um programa Lua consiste em vários tokens e um token é uma palavra-chave, um identificador, uma constante, um literal de string ou um símbolo. Por exemplo, a seguinte instrução Lua consiste em três tokens -

io.write("Hello world, from ",_VERSION,"!\n")

Os tokens individuais são -

io.write
(
   "Hello world, from ",_VERSION,"!\n"
)

Comentários

Os comentários são como texto de ajuda em seu programa Lua e são ignorados pelo interpretador. Eles começam com - [[e terminam com os caracteres -]] conforme mostrado abaixo -

--[[ my first program in Lua --]]

Identificadores

Um identificador Lua é um nome usado para identificar uma variável, função ou qualquer outro item definido pelo usuário. Um identificador começa com uma letra de 'A a Z' ou 'a a z' ou um sublinhado '_' seguido por zero ou mais letras, sublinhados e dígitos (0 a 9).

Lua não permite caracteres de pontuação como @, $ e% nos identificadores. Lua é umacase sensitivelinguagem de programação. Portanto, Manpower e manpower são dois identificadores diferentes em Lua. Aqui estão alguns exemplos de identificadores aceitáveis ​​-

mohd         zara      abc     move_name    a_123
myname50     _temp     j       a23b9        retVal

Palavras-chave

A lista a seguir mostra algumas das palavras reservadas em Lua. Essas palavras reservadas não podem ser usadas como constantes ou variáveis ​​ou quaisquer outros nomes de identificador.

e pausa Faz outro
elseif fim falso para
função E se dentro local
nada não ou repetir
Retorna então verdadeiro até
enquanto

Espaço em branco na Lua

Uma linha contendo apenas espaços em branco, possivelmente com um comentário, é conhecida como linha em branco e um interpretador Lua a ignora totalmente.

Espaço em branco é o termo usado em Lua para descrever espaços em branco, guias, caracteres de nova linha e comentários. O espaço em branco separa uma parte de uma instrução de outra e permite que o interpretador identifique onde um elemento em uma instrução, como int termina, e o próximo elemento começa. Portanto, na seguinte declaração -

local age

Deve haver pelo menos um caractere de espaço em branco (geralmente um espaço) entre local e idade para que o intérprete seja capaz de distingui-los. Por outro lado, na seguinte declaração -

fruit = apples + oranges   --get the total fruit

Nenhum caractere de espaço em branco é necessário entre frutas e =, ou entre = e maçãs, embora você seja livre para incluir alguns se desejar para fins de legibilidade.

Uma variável nada mais é que um nome dado a uma área de armazenamento que nossos programas podem manipular. Ele pode conter diferentes tipos de valores, incluindo funções e tabelas.

O nome de uma variável pode ser composto de letras, dígitos e o caractere de sublinhado. Deve começar com uma letra ou um sublinhado. Letras maiúsculas e minúsculas são distintas porque Lua faz distinção entre maiúsculas e minúsculas. Existem oito tipos básicos de valores em Lua -

Em Lua, embora não tenhamos tipos de dados variáveis, temos três tipos baseados no escopo da variável.

  • Global variables - Todas as variáveis ​​são consideradas globais, a menos que explicitamente declaradas como locais.

  • Local variables - Quando o tipo é especificado como local para uma variável, seu escopo é limitado com as funções dentro de seu escopo.

  • Table fields - Este é um tipo especial de variável que pode conter qualquer coisa, exceto nada, incluindo funções.

Definição de Variável em Lua

Uma definição de variável significa dizer ao interpretador onde e quanto criar o armazenamento para a variável. Uma definição de variável tem um tipo opcional e contém uma lista de uma ou mais variáveis ​​desse tipo como segue -

type variable_list;

Aqui, type é opcionalmente local ou tipo especificado, tornando-o global, e variable_listpode consistir em um ou mais nomes de identificadores separados por vírgulas. Algumas declarações válidas são mostradas aqui -

local    i, j
local    i
local    a,c

A linha local i, jambos declaram e definem as variáveis ​​i e j; que instrui o interpretador a criar variáveis ​​chamadas i, j e limita o escopo a ser local.

As variáveis ​​podem ser inicializadas (atribuídas a um valor inicial) em sua declaração. O inicializador consiste em um sinal de igual seguido por uma expressão constante da seguinte maneira -

type variable_list = value_list;

Alguns exemplos são -

local d , f = 5 ,10     --declaration of d and f as local variables. 
d , f = 5, 10;          --declaration of d and f as global variables. 
d, f = 10               --[[declaration of d and f as global variables. 
                           Here value of f is nil --]]

Para definição sem um inicializador: variáveis ​​com duração de armazenamento estático são inicializadas implicitamente com nil.

Declaração de variável em Lua

Como você pode ver nos exemplos acima, as atribuições para variáveis ​​múltiplas seguem um formato lista_variável e lista_valor. No exemplo acimalocal d, f = 5,10 temos d e f na lista_variável e 5 e 10 na lista de valores.

A atribuição de valor em Lua ocorre como a primeira variável na lista_variável com o primeiro valor na lista_valor e assim por diante. Portanto, o valor de d é 5 e o valor de f é 10.

Exemplo

Tente o exemplo a seguir, onde as variáveis ​​foram declaradas no topo, mas foram definidas e inicializadas dentro da função principal -

-- 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)

print("value of b:", b)

f = 70.0/3.0
print("value of f", f)

Quando o código acima é construído e executado, ele produz o seguinte resultado -

value of a:	10
value of b:	30
value of a:	30
value of b:	10
value of f	23.333333333333

Lvalues ​​e Rvalues ​​na Lua

Existem dois tipos de expressões em Lua -

  • lvalue- As expressões que se referem a um local da memória são chamadas de expressão "lvalue". Um lvalue pode aparecer como o lado esquerdo ou direito de uma atribuição.

  • rvalue- O termo rvalue se refere a um valor de dados que é armazenado em algum endereço da memória. Um rvalue é uma expressão que não pode ter um valor atribuído a ela, o que significa que um rvalue pode aparecer no lado direito, mas não no lado esquerdo de uma atribuição.

As variáveis ​​são lvalues ​​e, portanto, podem aparecer no lado esquerdo de uma atribuição. Literais numéricos são rvalues ​​e, portanto, não podem ser atribuídos e não podem aparecer no lado esquerdo. A seguir está uma declaração válida -

g = 20

Mas a seguir não é uma declaração válida e geraria um erro de tempo de construção -

10 = 20

Na linguagem de programação Lua, além dos tipos de atribuição acima, é possível ter vários lvalues ​​e rvalues ​​no mesmo comando. É mostrado abaixo.

g,l = 20,30

Na declaração acima, 20 é atribuído a ge 30 é atribuído a l.

Lua é uma linguagem tipada dinamicamente, então as variáveis ​​não têm tipos, apenas os valores têm tipos. Os valores podem ser armazenados em variáveis, passados ​​como parâmetros e retornados como resultados.

Em Lua, embora não tenhamos tipos de dados variáveis, temos tipos para os valores. A lista de tipos de dados para valores é fornecida abaixo.

Sr. Não Tipo de valor e descrição
1

nil

Usado para diferenciar o valor de ter alguns dados ou nenhum dado (nulo).

2

boolean

Inclui verdadeiro e falso como valores. Geralmente usado para verificação de condições.

3

number

Representa números reais (ponto flutuante de precisão dupla).

4

string

Representa matriz de caracteres.

5

function

Representa um método escrito em C ou Lua.

6

userdata

Representa dados C arbitrários.

7

thread

Representa threads de execução independentes e é usado para implementar co-rotinas.

8

table

Representa matrizes comuns, tabelas de símbolos, conjuntos, registros, gráficos, árvores, etc., e implementa matrizes associativas. Ele pode conter qualquer valor (exceto nulo).

Função de tipo

Em Lua, existe uma função chamada 'tipo' que nos permite saber o tipo da variável. Alguns exemplos são fornecidos no código a seguir.

print(type("What is my type"))   --> string
t = 10

print(type(5.8*t))               --> number
print(type(true))                --> boolean
print(type(print))               --> function
print(type(nil))                 --> nil
print(type(type(ABC)))           --> string

Quando você constrói e executa o programa acima, ele produz o seguinte resultado no Linux -

string
number
boolean
function
nil
string

Por padrão, todas as variáveis ​​apontarão para nil até que recebam um valor ou sejam inicializadas. Em Lua, cadeias de caracteres zero e vazias são consideradas verdadeiras no caso de verificações de condição. Portanto, você deve ter cuidado ao usar operações booleanas. Saberemos mais sobre esses tipos nos próximos capítulos.

Um operador é um símbolo que diz ao intérprete para realizar manipulações matemáticas ou lógicas específicas. A linguagem Lua é rica em operadores integrados e fornece os seguintes tipos de operadores -

  • Operadores aritméticos
  • Operadores Relacionais
  • Operadores lógicos
  • Operadores diversos

Este tutorial explicará os operadores aritméticos, relacionais, lógicos e outros operadores diversos, um por um.

Operadores aritméticos

A tabela a seguir mostra todos os operadores aritméticos suportados pela linguagem Lua. Assumir variávelA contém 10 e variável B detém 20 então -

Mostrar exemplos

Operador Descrição Exemplo
+ Adiciona dois operandos A + B dará 30
- Subtrai o segundo operando do primeiro A - B dará -10
* Multiplique os dois operandos A * B dará 200
/ Divide numerador por de-numerador B / A dará 2
% Operador de Módulo e o restante após uma divisão inteira B% A dará 0
^ O operador expoente pega os expoentes A ^ 2 dará 100
- Unário - operador atua como negação -A dará -10

Operadores Relacionais

A tabela a seguir mostra todos os operadores relacionais suportados pela linguagem Lua. Assumir variávelA contém 10 e variável B detém 20 então -

Mostrar exemplos

Operador Descrição Exemplo
== Verifica se os valores de dois operandos são iguais ou não, se sim a condição torna-se verdadeira. (A == B) não é verdade.
~ = Verifica se o valor de dois operandos são iguais ou não; se os valores não são iguais, a condição se torna verdadeira. (A ~ = B) é verdade.
> Verifica se o valor do operando esquerdo é maior que o valor do operando direito, se sim então a condição torna-se verdadeira. (A> B) não é verdade.
< Verifica se o valor do operando esquerdo é menor que o valor do operando direito; se sim, a condição torna-se verdadeira. (A <B) é verdade.
> = Verifica se o valor do operando esquerdo é maior ou igual ao valor do operando direito, se sim a condição torna-se verdadeira. (A> = B) não é verdade.
<= Verifica se o valor do operando esquerdo é menor ou igual ao valor do operando direito; em caso afirmativo, a condição torna-se verdadeira. (A <= B) é verdadeiro.

Operadores lógicos

A tabela a seguir mostra todos os operadores lógicos suportados pela linguagem Lua. Assumir variávelA é verdadeiro e variável B é falso então -

Mostrar exemplos

Operador Descrição Exemplo
e Operador lógico chamado AND. Se ambos os operandos forem diferentes de zero, a condição se torna verdadeira. (A e B) é falso.
ou Operador lógico ou chamado. Se qualquer um dos dois operandos for diferente de zero, a condição se torna verdadeira. (A ou B) é verdade.
não Operador lógico chamado NOT. Use para reverter o estado lógico de seu operando. Se uma condição for verdadeira, o operador NOT lógico tornará falso. ! (A e B) é verdade.

Operadores diversos

Operadores diversos suportados pela linguagem Lua incluem concatenation e length.

Mostrar exemplos

Operador Descrição Exemplo
.. Concatena duas strings. a..b onde a é "Hello" eb é "World", retornará "Hello World".
# Um operador unário que retorna o comprimento de uma string ou de uma tabela. # "Hello" retornará 5

Precedência de operadores em Lua

A precedência do operador determina o agrupamento de termos em uma expressão. Isso afeta como uma expressão é avaliada. Certos operadores têm precedência mais alta do que outros; por exemplo, o operador de multiplicação tem precedência mais alta do que o operador de adição -

Por exemplo, x = 7 + 3 * 2; Aqui, x é atribuído a 13, não 20, porque o operador * tem precedência mais alta do que +, portanto, primeiro é multiplicado por 3 * 2 e, em seguida, é adicionado a 7.

Aqui, os operadores com a precedência mais alta aparecem na parte superior da tabela, aqueles com a mais baixa aparecem na parte inferior. Em uma expressão, os operadores de precedência superior serão avaliados primeiro.

Mostrar exemplos

Categoria Operador Associatividade
Unário não # - Direita para esquerda
Concatenação .. Direita para esquerda
Multiplicativo * /% Da esquerda para direita
Aditivo + - Da esquerda para direita
Relacional <> <=> = == ~ =  Da esquerda para direita
Igualdade == ~ = Da esquerda para direita
E lógico e Da esquerda para direita
OR lógico ou Da esquerda para direita

Pode haver uma situação em que você precise executar um bloco de código várias vezes. Em geral, as instruções são executadas sequencialmente: a primeira instrução em uma função é executada primeiro, seguida pela segunda e assim por diante.

As linguagens de programação fornecem várias estruturas de controle que permitem caminhos de execução mais complicados.

Uma instrução de loop nos permite executar uma instrução ou grupo de instruções várias vezes. A seguir está a forma geral de uma instrução de loop na maioria das linguagens de programação -

Lua fornece os seguintes tipos de loops para lidar com os requisitos de loop.

Sr. Não. Tipo de Loop e Descrição
1 loop while

Repete uma declaração ou grupo de declarações enquanto uma determinada condição for verdadeira. Ele testa a condição antes de executar o corpo do loop.

2 para loop

Executa uma sequência de instruções várias vezes e abrevia o código que gerencia a variável de loop.

3 repetir ... até o loop

Repete a operação do grupo de instruções até que a condição until seja atendida.

4 loops aninhados

Você pode usar um ou mais loops dentro de qualquer outro loop while, for ou do..while .

Declaração de controle de loop

A instrução de controle de loop altera a execução de sua sequência normal. Quando a execução deixa um escopo, todos os objetos automáticos que foram criados nesse escopo são destruídos.

Lua suporta as seguintes instruções de controle.

Sr. Não. Declaração de controle e descrição
1 declaração de quebra

Termina o loop e transfere a execução para a instrução imediatamente após o loop ou switch.

The Infinite Loop

Um loop se torna um loop infinito se uma condição nunca se torna falsa. owhileloop é freqüentemente usado para este propósito. Como fornecemos true diretamente para a condição, ela continua em execução para sempre. Podemos usar a instrução break para interromper esse loop.

while( true )
do
   print("This loop will run forever.")
end

As estruturas de tomada de decisão requerem que o programador especifique uma ou mais condições a serem avaliadas ou testadas pelo programa, juntamente com uma instrução ou instruções a serem executadas, se a condição for determinada como verdadeira, e, opcionalmente, outras instruções a serem executadas se o condição é determinada como falsa.

A seguir está a forma geral de uma estrutura típica de tomada de decisão encontrada na maioria das linguagens de programação -

A linguagem de programação Lua assume qualquer combinação de Boolean true e non-nil valores como true, e se for booleano false ou nil, então é assumido como falsevalor. Deve-se notar que em Lua,zero will be considered as true.

A linguagem de programação Lua fornece os seguintes tipos de instruções de tomada de decisão.

Sr. Não. Declaração e descrição
1 declaração if

Uma instrução if consiste em uma expressão booleana seguida por uma ou mais instruções.

2 declaração if ... else

Uma instrução if pode ser seguida por uma instrução else opcional , que é executada quando a expressão booleana é falsa.

3 declarações if aninhadas

Você pode usar uma instrução if ou else if dentro de outra instrução if ou else if .

Uma função é um grupo de instruções que, juntas, executam uma tarefa. Você pode dividir seu código em funções separadas. Como você divide seu código entre diferentes funções é com você, mas logicamente a divisão geralmente única, é para que cada função execute uma tarefa específica.

A linguagem Lua fornece vários métodos integrados que seu programa pode chamar. Por exemplo, métodoprint() para imprimir o argumento passado como entrada no console.

Uma função é conhecida por vários nomes, como um método ou uma sub-rotina ou um procedimento, etc.

Definindo uma função

A forma geral de definição de um método na linguagem de programação Lua é a seguinte -

optional_function_scope function function_name( argument1, argument2, argument3........, 
argumentn)
function_body
return result_params_comma_separated
end

Uma definição de método na linguagem de programação Lua consiste em um cabeçalho de método e um corpo de método . Aqui estão todas as partes de um método -

  • Optional Function Scope- Você pode usar a palavra-chave local para limitar o escopo da função ou ignorar a seção de escopo, o que a tornará uma função global.

  • Function Name- Este é o nome real da função. O nome da função e a lista de parâmetros juntos constituem a assinatura da função.

  • Arguments- Um argumento é como um espaço reservado. Quando uma função é chamada, você passa um valor para o argumento. Esse valor é conhecido como o parâmetro ou argumento real. A lista de parâmetros se refere ao tipo, ordem e número dos argumentos de um método. Os argumentos são opcionais; ou seja, um método não pode conter nenhum argumento.

  • Function Body - O corpo do método contém uma coleção de instruções que definem o que o método faz.

  • Return - Em Lua, é possível retornar vários valores seguindo a palavra-chave return com os valores de retorno separados por vírgula.

Exemplo

A seguir está o código-fonte para uma função chamada max(). Esta função recebe dois parâmetros num1 e num2 e retorna o máximo entre os dois -

--[[ function returning the max between two numbers --]]
function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   return result; 
end

Argumentos de função

Se uma função deve usar argumentos, ela deve declarar as variáveis ​​que aceitam os valores dos argumentos. Essas variáveis ​​são chamadas deformal parameters da função.

Os parâmetros formais se comportam como outras variáveis ​​locais dentro da função e são criados na entrada na função e destruídos na saída.

Chamando uma função

Ao criar uma função Lua, você dá uma definição do que a função deve fazer. Para usar um método, você terá que chamar essa função para executar a tarefa definida.

Quando um programa chama uma função, o controle do programa é transferido para a função chamada. Uma função chamada executa a tarefa definida e quando sua instrução de retorno é executada ou quando o fim de sua função é alcançado, ela retorna o controle do programa para o programa principal.

Para chamar um método, você simplesmente precisa passar os parâmetros necessários junto com o nome do método e, se o método retornar um valor, você pode armazenar o valor retornado. Por exemplo -

function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   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))

Quando executarmos o código acima, obteremos a seguinte saída.

The maximum of the two numbers is 	10
The maximum of the two numbers is 	6

Atribuição e aprovação de funções

Em Lua, podemos atribuir a função a variáveis ​​e também passá-las como parâmetros de outra função. Aqui está um exemplo simples para atribuir e passar uma função como parâmetro em Lua.

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)

Quando executarmos o código acima, obteremos a seguinte saída.

This is my print function -   ##	10	##
This is my print function -   ##	7	##

Função com argumento variável

É possível criar funções com argumentos variáveis ​​em Lua usando '...' como parâmetro. Podemos entender isso vendo um exemplo em que a função retornará a média e pode receber argumentos variáveis.

function average(...)
   result = 0
   local arg = {...}
   for i,v in ipairs(arg) do
      result = result + v
   end
   return result/#arg
end

print("The average is",average(10,5,3,4,5,6))

Quando executarmos o código acima, obteremos a seguinte saída.

The average is	5.5

String é uma sequência de caracteres, bem como caracteres de controle, como alimentação de formulário. A string pode ser inicializada com três formas que incluem -

  • Caracteres entre aspas simples
  • Caracteres entre aspas duplas
  • Personagens entre [[e]]

Um exemplo para os três formulários acima é mostrado abaixo.

string1 = "Lua"
print("\"String 1 is\"",string1)

string2 = 'Tutorial'
print("String 2 is",string2)

string3 = [["Lua Tutorial"]]
print("String 3 is",string3)

Quando executamos o programa acima, obteremos a seguinte saída.

"String 1 is" Lua
String 2 is	Tutorial
String 3 is	"Lua Tutorial"

Os caracteres da sequência de escape são usados ​​na string para alterar a interpretação normal dos caracteres. Por exemplo, para imprimir as vírgulas duplas invertidas (""), usamos \ "no exemplo acima. A seqüência de escape e seu uso estão listados abaixo na tabela.

Sequência de fuga Usar
\uma Sino
\ b Backspace
\ f Formfeed
\ n Nova linha
\ r Retorno de carruagem
\ t Aba
\ v Aba vertical
\\ Barra invertida
\ " Aspas duplas
\ ' Aspas simples
\ [ Colchete esquerdo
\] Colchete direito

Manipulação de Cordas

Lua suporta string para manipular strings -

Sr. Não. Método e Objetivo
1

string.upper(argument)

Retorna uma representação do argumento em maiúscula.

2

string.lower(argument)

Retorna uma representação em minúsculas do argumento.

3

string.gsub(mainString,findString,replaceString)

Retorna uma string substituindo as ocorrências de findString por replaceString.

4

string.find(mainString,findString,

optionalStartIndex,optionalEndIndex)

Retorna o índice inicial e o índice final de findString na string principal e nil se não for encontrado.

5

string.reverse(arg)

Retorna uma string revertendo os caracteres da string passada.

6

string.format(...)

Retorna uma string formatada.

7

string.char(arg) and string.byte(arg)

Retorna representações numéricas internas e de caracteres do argumento de entrada.

8

string.len(arg)

Retorna o comprimento da string passada.

9

string.rep(string, n))

Retorna uma string repetindo a mesma string n número de vezes.

10

..

Assim, o operador concatena duas strings.

Agora, vamos mergulhar em alguns exemplos para ver exatamente como essas funções de manipulação de string se comportam.

Manipulação de Caso

Um código de exemplo para manipular as strings para maiúsculas e minúsculas é fornecido abaixo.

string1 = "Lua";

print(string.upper(string1))
print(string.lower(string1))

Quando executamos o programa acima, obteremos a seguinte saída.

LUA
lua

Substituindo uma Substring

Um exemplo de código para substituir as ocorrências de uma string por outra é fornecido a seguir.

string = "Lua Tutorial"

-- replacing strings
newstring = string.gsub(string,"Tutorial","Language")
print("The new string is "..newstring)

Quando executamos o programa acima, obteremos a seguinte saída.

The new string is Lua Language

Descobrindo e revertendo

Um código de exemplo para localizar o índice de substring e reverter a string é fornecido abaixo.

string = "Lua Tutorial"

-- replacing strings
print(string.find(string,"Tutorial"))
reversedString = string.reverse(string)
print("The new string is",reversedString)

Quando executamos o programa acima, obteremos a seguinte saída.

5	12
The new string is	lairotuT auL

Formatando Strings

Muitas vezes em nossa programação, podemos precisar imprimir strings de forma formatada. Você pode usar a função string.format para formatar a saída conforme mostrado abaixo.

string1 = "Lua"
string2 = "Tutorial"

number1 = 10
number2 = 20

-- Basic string formatting
print(string.format("Basic formatting %s %s",string1,string2))

-- Date formatting
date = 2; month = 1; year = 2014
print(string.format("Date formatting %02d/%02d/%03d", date, month, year))

-- Decimal formatting
print(string.format("%.4f",1/3))

Quando executamos o programa acima, obteremos a seguinte saída.

Basic formatting Lua Tutorial
Date formatting 02/01/2014
0.3333

Representações de caracteres e bytes

Um código de amostra para representação de caractere e byte, que é usado para converter a string de string para representação interna e vice-versa.

-- 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))

-- Internal Numeric ASCII Conversion
print(string.char(97))

Quando executamos o programa acima, obteremos a seguinte saída.

76
97
97
117
117
a

Outras funções comuns

As manipulações comuns de string incluem concatenação de string, localização do comprimento da string e, às vezes, repetição da mesma string várias vezes. O exemplo para essas operações é fornecido abaixo.

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)

Quando executamos o programa acima, obteremos a seguinte saída.

Concatenated string	LuaTutorial
Length of string1 is 	3
LuaLuaLua

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.

Matriz unidimensional

Uma matriz unidimensional pode ser representada usando uma estrutura de tabela simples e pode ser inicializada e lida usando um simples forciclo. Um exemplo é mostrado abaixo.

array = {"Lua", "Tutorial"}

for i = 0, 2 do
   print(array[i])
end

Quando executarmos o código acima, obteremos a seguinte saída.

nil
Lua
Tutorial

Como você pode ver no código acima, quando tentamos acessar um elemento em um índice que não está no array, ele retorna nil. Em Lua, a indexação geralmente começa no índice 1. Mas é possível criar objetos no índice 0 e abaixo de 0 também. O array usando índices negativos é mostrado abaixo, onde inicializamos o array usando um loop for .

array = {}

for i= -2, 2 do
   array[i] = i *2
end

for i = -2,2 do
   print(array[i])
end

Quando executarmos o código acima, obteremos a seguinte saída.

-4
-2
0
2
4

Matriz Multi-Dimensional

Arrays multidimensionais podem ser implementados de duas maneiras.

  • Matriz de matrizes
  • Matriz unidimensional manipulando índices

Um exemplo de array multidimensional de 3. 3 é mostrado abaixo usando array de arrays.

-- Initializing the array
array = {}

for i=1,3 do
   array[i] = {}
	
   for j=1,3 do
      array[i][j] = i*j
   end
	
end

-- Accessing the array

for i=1,3 do

   for j=1,3 do
      print(array[i][j])
   end
	
end

Quando executarmos o código acima, obteremos a seguinte saída.

1
2
3
2
4
6
3
6
9

Um exemplo de array multidimensional é mostrado abaixo usando índices de manipulação.

-- Initializing the array

array = {}

maxRows = 3
maxColumns = 3

for row=1,maxRows do

   for col=1,maxColumns do
      array[row*maxColumns +col] = row*col
   end
	
end

-- Accessing the array

for row=1,maxRows do

   for col=1,maxColumns do
      print(array[row*maxColumns +col])
   end
	
end

Quando executarmos o código acima, obteremos a seguinte saída.

1
2
3
2
4
6
3
6
9

Como você pode ver no exemplo acima, os dados são armazenados com base em índices. É possível colocar os elementos de forma esparsa e é assim que funciona a implementação de uma matriz em Lua. Como ele não armazena valores nulos em Lua, é possível economizar muita memória sem nenhuma técnica especial em Lua, em comparação com as técnicas especiais usadas em outras linguagens de programação.

Iterator é uma construção que permite percorrer os elementos da chamada coleção ou contêiner. Em Lua, essas coleções geralmente se referem a tabelas, que são usadas para criar várias estruturas de dados, como array.

Genérico para Iterator

Um genérico para iterador fornece os pares de valores-chave de cada elemento na coleção. Um exemplo simples é fornecido abaixo.

array = {"Lua", "Tutorial"}

for key,value in ipairs(array) 
do
   print(key, value)
end

Quando executarmos o código acima, obteremos a seguinte saída -

1  Lua
2  Tutorial

O exemplo acima usa a função iteradora ipairs padrão fornecida por Lua.

Em Lua, usamos funções para representar iteradores. Com base na manutenção de estado nessas funções de iterador, temos dois tipos principais -

  • Iteradores sem estado
  • Iteradores com estado

Iteradores sem estado

Pelo próprio nome podemos entender que este tipo de função iterativa não retém nenhum estado.

Vejamos agora um exemplo de criação de nosso próprio iterador usando uma função simples que imprime os quadrados de n números.

function square(iteratorMaxCount,currentNumber)

   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
      return currentNumber, currentNumber*currentNumber
   end
	
end

for i,n in square,3,0
do
   print(i,n)
end

Quando executamos o programa acima, obteremos a seguinte saída.

1	1
2	4
3	9

O código acima pode ser modificado ligeiramente para imitar a maneira como a função ipairs dos iteradores funciona. É mostrado abaixo.

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  

for i,n in squares(3)
do 
   print(i,n)
end

Quando executamos o programa acima, obteremos a seguinte saída.

1	1
2	4
3	9

Iteradores com estado

O exemplo anterior de iteração usando função não retém o estado. Cada vez que a função é chamada, ela retorna o próximo elemento da coleção com base em uma segunda variável enviada para a função. Para manter o estado do elemento atual, fechamentos são usados. O fechamento retém os valores das variáveis ​​nas chamadas de funções. Para criar um novo fecho, criamos duas funções, incluindo o próprio fecho e uma fábrica, a função que cria o fecho.

Vejamos agora um exemplo de criação de nosso próprio iterador no qual usaremos fechamentos.

array = {"Lua", "Tutorial"}

function elementIterator (collection)

   local index = 0
   local count = #collection
	
   -- The closure function is returned
	
   return function ()
      index = index + 1
		
      if index <= count
      then
         -- return the current element of the iterator
         return collection[index]
      end
		
   end
	
end

for element in elementIterator(array)
do
   print(element)
end

Quando executamos o programa acima, obteremos a seguinte saída.

Lua
Tutorial

No exemplo acima, podemos ver que elementIterator tem outro método interno que usa o índice de variáveis ​​externas locais e contagem para retornar cada um dos elementos na coleção, incrementando o índice cada vez que a função é chamada.

Podemos criar nossos próprios iteradores de função usando o fechamento conforme mostrado acima e ele pode retornar vários elementos para cada vez que iteramos na coleção.

Introdução

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.

Representação e Uso

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.

--sample table initialization
mytable = {}

--simple table value assignment
mytable[1]= "Lua"

--removing reference
mytable = nil

-- lua garbage collection will take care of releasing memory

Quando temos uma mesa a com um conjunto de elementos e se o atribuirmos a b, ambos a e breferem-se à mesma memória. Nenhuma memória separada é alocada separadamente para b. Quando a é definido como nulo, a tabela ainda estará acessível para b. Quando não há referência a uma tabela, a coleta de lixo em Lua cuida do processo de limpeza para fazer com que essa memória não referenciada seja reutilizada novamente.

Um exemplo é mostrado abaixo para explicar os recursos das tabelas mencionados acima.

-- Simple empty table
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"])

-- alternatetable and mytable refers to same table
alternatetable = mytable

print("alternatetable Element at index 1 is ", alternatetable[1])
print("alternatetable Element at index wow is ", alternatetable["wow"])

alternatetable["wow"] = "I changed it"

print("mytable Element at index wow is ", mytable["wow"])

-- only variable released and and not table
alternatetable = nil
print("alternatetable is ", alternatetable)

-- mytable is still accessible
print("mytable Element at index wow is ", mytable["wow"])

mytable = nil
print("mytable is ", mytable)

Quando executamos o programa acima, obteremos a seguinte saída -

Type of mytable is 	table
mytable Element at index 1 is 	Lua
mytable Element at index wow is 	Tutorial
alternatetable Element at index 1 is 	Lua
alternatetable Element at index wow is 	Tutorial
mytable Element at index wow is 	I changed it
alternatetable is 	nil
mytable Element at index wow is 	I changed it
mytable is 	nil

Manipulação de Tabela

Existem funções incorporadas para manipulação de tabelas e estão listadas na tabela a seguir.

Sr. Não. Método e Objetivo
1

table.concat (table [, sep [, i [, j]]])

Concatena as strings nas tabelas com base nos parâmetros fornecidos. Veja o exemplo para detalhes.

2

table.insert (table, [pos,] value)

Insere um valor na tabela na posição especificada.

3

table.maxn (table)

Retorna o maior índice numérico.

4

table.remove (table [, pos])

Remove o valor da tabela.

5

table.sort (table [, comp])

Classifica a tabela com base no argumento do comparador opcional.

Vamos ver alguns exemplos das funções acima.

Concatenação de Tabela

Podemos usar a função concat para concatenar duas tabelas como mostrado abaixo -

fruits = {"banana","orange","apple"}

-- returns concatenated string of table
print("Concatenated string ",table.concat(fruits))

--concatenate with a character
print("Concatenated string ",table.concat(fruits,", "))

--concatenate fruits based on index
print("Concatenated string ",table.concat(fruits,", ", 2,3))

Quando executamos o programa acima, obteremos a seguinte saída -

Concatenated string 	bananaorangeapple
Concatenated string 	banana, orange, apple
Concatenated string 	orange, apple

Inserir e remover

A inserção e remoção de itens em tabelas são mais comuns na manipulação de tabelas. Isso é explicado a seguir.

fruits = {"banana","orange","apple"}

-- insert a fruit at the end
table.insert(fruits,"mango")
print("Fruit at index 4 is ",fruits[4])

--insert fruit at index 2
table.insert(fruits,2,"grapes")
print("Fruit at index 2 is ",fruits[2])

print("The maximum elements in table is",table.maxn(fruits))

print("The last element is",fruits[5])

table.remove(fruits)
print("The previous last element is",fruits[5])

Quando executarmos o programa acima, obteremos a seguinte saída -

Fruit at index 4 is 	mango
Fruit at index 2 is 	grapes
The maximum elements in table is	5
The last element is	mango
The previous last element is	nil

Classificando tabelas

Freqüentemente, precisamos classificar uma tabela em uma ordem específica. As funções de classificação classificam os elementos em uma tabela em ordem alfabética. Um exemplo disso é mostrado abaixo.

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

Quando executamos o programa acima, obteremos a seguinte saída -

1	banana
2	orange
3	apple
4	grapes
sorted table
1	apple
2	banana
3	grapes
4	orange

O que é um módulo?

O módulo é como uma biblioteca que pode ser carregada usando require e tem um único nome global contendo uma tabela. Este módulo pode consistir em várias funções e variáveis. Todas essas funções e variáveis ​​são agrupadas na tabela, que atua como um namespace. Além disso, um módulo bem comportado tem as disposições necessárias para retornar esta tabela quando necessário.

Especialidade de Módulos Lua

O uso de tabelas em módulos nos ajuda de várias maneiras e nos permite manipular os módulos da mesma forma que manipulamos qualquer outra tabela Lua. Como resultado da capacidade de manipular módulos, ele fornece recursos extras para os quais outras linguagens precisam de mecanismos especiais. Devido a esse mecanismo livre de módulos em Lua, um usuário pode chamar as funções em Lua de várias maneiras. Alguns deles são mostrados abaixo.

-- Assuming we have a module printFormatter
-- Also printFormatter has a funtion simpleFormat(arg)
-- Method 1
require "printFormatter"
printFormatter.simpleFormat("test")

-- Method 2
local formatter = require "printFormatter"
formatter.simpleFormat("test")

-- Method 3
require "printFormatter"
local formatterFunction = printFormatter.simpleFormat
formatterFunction("test")

No código de exemplo acima, você pode ver como a programação em Lua é flexível, sem nenhum código adicional especial.

A função require

Lua forneceu uma função de alto nível chamada require para carregar todos os módulos necessários. É mantido o mais simples possível para evitar ter muitas informações sobre o módulo para carregá-lo. A função require apenas assume os módulos como um pedaço de código que define alguns valores, que na verdade são funções ou tabelas contendo funções.

Exemplo

Vamos considerar um exemplo simples, onde uma função tem as funções matemáticas. Vamos chamar esse módulo de mymath e o nome de arquivo como mymath.lua. O conteúdo do arquivo é o seguinte -

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

Agora, para acessar este módulo Lua em outro arquivo, digamos, moduletutorial.lua, você precisa usar o seguinte segmento de código.

mymathmodule = require("mymath")
mymathmodule.add(10,20)
mymathmodule.sub(30,20)
mymathmodule.mul(10,20)
mymathmodule.div(30,20)

Para executar este código, precisamos colocar os dois arquivos Lua no mesmo diretório ou, alternativamente, você pode colocar o arquivo do módulo no caminho do pacote e ele precisa de configuração adicional. Quando executamos o programa acima, obteremos a seguinte saída.

30
10
200
1.5

Coisas para lembrar

  • Coloque os módulos e o arquivo que você executa no mesmo diretório.

  • O nome do módulo e seu nome de arquivo devem ser iguais.

  • É uma prática recomendada retornar módulos para a função necessária e, portanto, o módulo deve ser preferencialmente implementado conforme mostrado acima, embora você possa encontrar outros tipos de implementações em outro lugar.

Antiga maneira de implementar módulos

Deixe-me agora reescrever o mesmo exemplo da maneira mais antiga, que usa o tipo de implementação package.seeall. Isso foi usado nas versões 5.1 e 5.0 da Lua. O módulo mymath é mostrado abaixo.

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)
end

function mymath.div(a,b)
   print(a/b)
end

O uso de módulos em moduletutorial.lua é mostrado abaixo.

require("mymath")
mymath.add(10,20)
mymath.sub(30,20)
mymath.mul(10,20)
mymath.div(30,20)

Quando executarmos o procedimento acima, obteremos a mesma saída. Mas é aconselhável usar a versão mais antiga do código e é considerado menos seguro. Muitos SDKs que usam Lua para programação, como o Corona SDK, tornaram seu uso obsoleto.

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 -

  • Alterar / adicionar funcionalidades aos operadores nas mesas.

  • Procurando meta-tabelas quando a chave não está disponível na tabela usando __index na meta-tabela.

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

  • setmetatable(table,metatable) - Este método é usado para definir uma meta-tabela para uma tabela.

  • getmetatable(table) - Este método é usado para obter a metatabela de uma tabela.

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

mytable = {}
mymetatable = {}
setmetatable(mytable,mymetatable)

O código acima pode ser representado em uma única linha, conforme mostrado abaixo.

mytable = setmetatable({},{})

_índice

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

mytable = setmetatable({key1 = "value1"}, {
   __index = function(mytable, key)
	
      if key == "key2" then
         return "metatablevalue"
      else
         return mytable[key]
      end
   end
})

print(mytable.key1,mytable.key2)

Quando executamos o programa acima, obteremos a seguinte saída.

value1 metatablevalue

Vamos explicar o que aconteceu no exemplo acima em etapas.

  • A mesa minha mesa aqui é {key1 = "value1"}.

  • Metatable é definido para mytable que contém uma função para __index, que chamamos como um metamétodo.

  • O metamétodo faz um trabalho simples de procurar um índice "key2", se for encontrado, ele retorna "metatablevalue", caso contrário, retorna o valor de mytable para o índice correspondente.

Podemos ter uma versão simplificada do programa acima, conforme mostrado abaixo.

mytable = setmetatable({key1 = "value1"}, 
   { __index = { key2 = "metatablevalue" } })
print(mytable.key1,mytable.key2)

__newindex

Quando adicionamos __newindex à metatabela, se as chaves não estiverem disponíveis na tabela, o comportamento das novas chaves será definido por métodos meta. Um exemplo simples onde o índice da metatabela é definido quando o índice não está disponível na tabela principal é fornecido abaixo.

mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })

print(mytable.key1)

mytable.newkey = "new value 2"
print(mytable.newkey,mymetatable.newkey)

mytable.key1 = "new  value 1"
print(mytable.key1,mymetatable.newkey1)

Quando você executa o programa acima, obtém a seguinte saída.

value1
nil	new value 2
new  value 1	nil

Você pode ver no programa acima, se existe uma chave na tabela principal, ele apenas a atualiza. Quando uma chave não está disponível na manutenção, ele adiciona essa chave à metatabela.

Outro exemplo que atualiza a mesma tabela usando a função rawset é mostrado abaixo.

mytable = setmetatable({key1 = "value1"}, {

   __newindex = function(mytable, key, value)
      rawset(mytable, key, "\""..value.."\"")
   end
})

mytable.key1 = "new value"
mytable.key2 = 4

print(mytable.key1,mytable.key2)

Quando executamos o programa acima, obteremos a seguinte saída.

new value	"4"

rawset define o valor sem usar __newindex de metatabela. Da mesma forma, há rawget que obtém valor sem usar __index.

Adicionando o comportamento do operador às tabelas

Um exemplo simples para combinar duas tabelas usando o operador + é mostrado abaixo -

mytable = setmetatable({ 1, 2, 3 }, {
   __add = function(mytable, newtable)
	
      for i = 1, table.maxn(newtable) do
         table.insert(mytable, table.maxn(mytable)+1,newtable[i])
      end
      return mytable
   end
})

secondtable = {4,5,6}

mytable = mytable + secondtable

for k,v in ipairs(mytable) do
   print(k,v)
end

Quando executamos o programa acima, obteremos a seguinte saída.

1	1
2	2
3	3
4	4
5	5
6	6

A chave __add é incluída na metatabela para adicionar o comportamento do operador +. A tabela de chaves e o operador correspondente são mostrados abaixo.

Sr. Não. Modo e descrição
1

__add

Altera o comportamento do operador '+'.

2

__sub

Muda o comportamento do operador '-'.

3

__mul

Altera o comportamento do operador '*'.

4

__div

Altera o comportamento do operador '/'.

5

__mod

Altera o comportamento do operador '%'.

6

__unm

Muda o comportamento do operador '-'.

7

__concat

Muda o comportamento do operador '..'.

8

__eq

Altera o comportamento do operador '=='.

9

__lt

Altera o comportamento do operador '<'.

10

__le

Altera o comportamento do operador '<='.

__ligar

Adicionar comportamento de chamada de método é feito usando a instrução __call. Um exemplo simples que retorna a soma dos valores da tabela principal com a tabela passada.

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))

Quando executamos o programa acima, obteremos a seguinte saída.

70

__para sequenciar

Para mudar o comportamento da instrução print, podemos usar o metamétodo __tostring. Um exemplo simples é mostrado abaixo.

mytable = setmetatable({ 10, 20, 30 }, {
   __tostring = function(mytable)
   sum = 0
	
      for k, v in pairs(mytable) do
         sum = sum + v
      end
		
      return "The sum of values in the table is " .. sum
   end
})
print(mytable)

Quando executamos o programa acima, obteremos a seguinte saída.

The sum of values in the table is 60

Se você conhece os recursos da metatabela totalmente, pode realmente realizar muitas operações que seriam muito complexas sem usá-la. Portanto, tente trabalhar mais no uso de meta-tabelas com diferentes opções disponíveis nas meta-tabelas, conforme explicado nos exemplos, e também crie seus próprios exemplos.

Introdução

As corrotinas são de natureza colaborativa, o que permite que dois ou mais métodos sejam executados de maneira controlada. Com co-rotinas, a qualquer momento, apenas uma co-rotina é executada e esta corrotina em execução apenas suspende sua execução quando solicita explicitamente para ser suspensa.

A definição acima pode parecer vaga. Vamos supor que temos dois métodos, um o método do programa principal e uma co-rotina. Quando chamamos uma co-rotina usando a função resume, ela começa a executar e quando chamamos a função yield, ela suspende a execução. Novamente, a mesma co-rotina pode continuar executando com outra chamada de função de retomada de onde foi suspensa. Este processo pode continuar até o final da execução da co-rotina.

Funções Disponíveis em Corrotinas

A tabela a seguir lista todas as funções disponíveis para co-rotinas em Lua e seu uso correspondente.

Sr. Não. Método e Objetivo
1

coroutine.create (f)

Cria uma nova co-rotina com uma função f e retorna um objeto do tipo "thread".

2

coroutine.resume (co [, val1, ...])

Retoma a co-rotina e passa os parâmetros, se houver. Ele retorna o status da operação e outros valores de retorno opcionais.

3

coroutine.running ()

Retorna a co-rotina em execução ou nil se chamado no thread principal.

4

coroutine.status (co)

Retorna um dos valores de execução, normal, suspenso ou morto com base no estado da co-rotina.

5

coroutine.wrap (f)

Como coroutine.create, a função coroutine.wrap também cria uma co-rotina, mas em vez de retornar a própria co-rotina, ela retorna uma função que, quando chamada, retoma a co-rotina.

6

coroutine.yield (...)

Suspende a co-rotina em execução. O parâmetro passado para este método atua como valores de retorno adicionais para a função de retomada.

Exemplo

Vejamos um exemplo para entender o conceito de corrotinas.

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)

print("main", coroutine.resume(co, 3, 2))
print("main", coroutine.resume(co, 12,14))
print("main", coroutine.resume(co, 5, 6))
print("main", coroutine.resume(co, 10, 20))

Quando executamos o programa acima, obteremos a seguinte saída.

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
main	true	2	end
main	false	cannot resume dead coroutine

O que o exemplo acima faz?

Como mencionado antes, usamos a função de retomada para iniciar a operação e a função de rendimento para interromper a operação. Além disso, você pode ver que existem vários valores de retorno recebidos pela função de retomada da co-rotina.

  • Primeiro, criamos uma co-rotina e atribuímos a ela um nome de variável co e a co-rotina recebe duas variáveis ​​como seus parâmetros.

  • Quando chamamos a primeira função de retomada, os valores 3 e 2 são retidos nas variáveis ​​temporárias valor1 e valor2 até o final da co-rotina.

  • Para que você entenda isso, usamos um tempvar3, que é 10 inicialmente e é atualizado para 13 e 16 pelas chamadas subsequentes das co-rotinas, já que value1 é mantido como 3 durante a execução da co-rotina.

  • O primeiro coroutine.yield retorna dois valores 4 e 3 para a função resume, que obtemos atualizando os parâmetros de entrada 3 e 2 na declaração de rendimento. Ele também recebe o status verdadeiro / falso da execução da co-rotina.

  • Outra coisa sobre corrotinas é como os próximos parâmetros de chamada de currículo são atendidos, no exemplo acima; você pode ver que a variável coroutine.yield recebe os próximos parâmetros de chamada, o que fornece uma maneira poderosa de fazer novas operações com a retenção de valores de parâmetros existentes.

  • Finalmente, uma vez que todas as instruções nas corrotinas sejam executadas, as chamadas subsequentes retornarão em falso e a instrução "não é possível retomar a co-rotina morta" como resposta.

Outro Exemplo de Corrotina

Vejamos uma co-rotina simples que retorna um número de 1 a 5 com a ajuda da função de rendimento e da função de retomada. Ele cria co-rotina se não estiver disponível ou então retoma a co-rotina existente.

function getNumber()
   local function getNumberHelper()
      co = coroutine.create(function ()
      coroutine.yield(1)
      coroutine.yield(2)
      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

Quando executamos o programa acima, obteremos a seguinte saída.

1	1
2	2
3	3
4	4
5	5
6	1
7	2
8	3
9	4
10	5

Freqüentemente, há uma comparação de co-rotinas com threads de linguagens de multiprogramação, mas precisamos entender que as corrotinas têm recursos semelhantes de thread, mas executam apenas uma de cada vez e nunca são executadas simultaneamente.

Controlamos a sequência de execução do programa para atender às necessidades com a prestação de reter certas informações temporariamente. Usar variáveis ​​globais com corrotinas fornece ainda mais flexibilidade para co-rotinas.

A biblioteca de E / S é usada para ler e manipular arquivos em Lua. Existem dois tipos de operações de arquivo em Lua, a saber, descritores de arquivo implícitos e descritores de arquivo explícitos.

Para os exemplos a seguir, usaremos um arquivo de amostra test.lua conforme mostrado abaixo.

-- sample test.lua
-- sample2 test.lua

Uma operação simples de abertura de arquivo usa a seguinte instrução.

file = io.open (filename [, mode])

Os vários modos de arquivo estão listados na tabela a seguir.

Sr. Não. Modo e descrição
1

"r"

O modo somente leitura é o modo padrão em que um arquivo existente é aberto.

2

"w"

Modo habilitado para gravação que sobrescreve o arquivo existente ou cria um novo arquivo.

3

"a"

Modo Anexar que abre um arquivo existente ou cria um novo arquivo para anexar.

4

"r+"

Modo de leitura e gravação para um arquivo existente.

5

"w+"

Todos os dados existentes são removidos se o arquivo existir ou se um novo arquivo for criado com permissões de leitura e gravação.

6

"a+"

Modo anexo com modo de leitura habilitado que abre um arquivo existente ou cria um novo arquivo.

Descritores de arquivo implícitos

Os descritores de arquivo implícitos usam os modos de entrada / saída padrão ou usam um único arquivo de entrada e saída. Um exemplo do uso de descritores de arquivo implícitos é mostrado abaixo.

-- Opens a file in read
file = io.open("test.lua", "r")

-- sets the default input file as test.lua
io.input(file)

-- prints the first line of the file
print(io.read())

-- closes the open file
io.close(file)

-- Opens a file in append mode
file = io.open("test.lua", "a")

-- sets the default output file as test.lua
io.output(file)

-- appends a word test to the last line of the file
io.write("-- End of the test.lua file")

-- closes the open file
io.close(file)

Ao executar o programa, você obterá uma saída da primeira linha do arquivo test.lua. Para nosso programa, obtivemos a seguinte saída.

-- Sample test.lua

Esta foi a primeira linha da instrução no arquivo test.lua para nós. Além disso, a linha "- Fim do arquivo test.lua" seria anexada à última linha do código test.lua.

No exemplo acima, você pode ver como os descritores implícitos funcionam com o sistema de arquivos usando os métodos io. "X". O exemplo acima usa io.read () sem o parâmetro opcional. O parâmetro opcional pode ser qualquer um dos seguintes.

Sr. Não. Modo e descrição
1

"*n"

Lê a partir da posição atual do arquivo e retorna um número se existir na posição do arquivo ou retorna nulo.

2

"*a"

Retorna todo o conteúdo do arquivo da posição atual do arquivo.

3

"*l"

Lê a linha da posição atual do arquivo e move a posição do arquivo para a próxima linha.

4

number

Lê o número de bytes especificados na função.

Outros métodos de I / O comuns incluem,

  • io.tmpfile() - Retorna um arquivo temporário para leitura e gravação que será removido assim que o programa for encerrado.

  • io.type(file) - Retorna se arquivo, arquivo fechado ou nulo com base no arquivo de entrada.

  • io.flush() - Limpa o buffer de saída padrão.

  • io.lines(optional file name)- Fornece um iterador de loop for genérico que percorre o arquivo e fecha o arquivo no final, caso o nome do arquivo seja fornecido ou o arquivo padrão seja usado e não fechado no final do loop.

Descritores explícitos de arquivo

Freqüentemente, usamos um descritor de arquivo explícito, o que nos permite manipular vários arquivos ao mesmo tempo. Essas funções são bastante semelhantes aos descritores de arquivo implícitos. Aqui, usamos file: function_name em vez de io.function_name. O exemplo a seguir da versão do arquivo do mesmo exemplo de descritores de arquivo implícitos é mostrado abaixo.

-- Opens a file in read mode
file = io.open("test.lua", "r")

-- prints the first line of the file
print(file:read())

-- closes the opened file
file:close()

-- Opens a file in append mode
file = io.open("test.lua", "a")

-- appends a word test to the last line of the file
file:write("--test")

-- closes the open file
file:close()

Ao executar o programa, você obterá uma saída semelhante ao exemplo dos descritores implícitos.

-- Sample test.lua

Todos os modos de abertura de arquivo e parâmetros de leitura para descritores externos são iguais aos descritores de arquivo implícitos.

Outros métodos de arquivo comuns incluem,

  • file:seek(optional whence, optional offset)- De onde o parâmetro é "set", "cur" ou "end". Define o novo ponteiro do arquivo com a posição do arquivo atualizada desde o início do arquivo. Os deslocamentos são baseados em zero nesta função. O deslocamento é medido a partir do início do arquivo se o primeiro argumento for "definido"; da posição atual no arquivo se for "cur"; ou do final do arquivo se for "final". Os valores de argumento padrão são "cur" e 0, portanto, a posição atual do arquivo pode ser obtida chamando esta função sem argumentos.

  • file:flush() - Limpa o buffer de saída padrão.

  • io.lines(optional file name)- Fornece um iterador de loop for genérico que percorre o arquivo e fecha o arquivo no final, caso o nome do arquivo seja fornecido ou o arquivo padrão seja usado e não fechado no final do loop.

Um exemplo para usar o método de busca é mostrado abaixo. Ele desloca o cursor das 25 posições anteriores ao final do arquivo. A função de leitura imprime o restante do arquivo da posição de busca.

-- Opens a file in read
file = io.open("test.lua", "r")

file:seek("end",-25)
print(file:read("*a"))

-- closes the opened file
file:close()

Você obterá alguma saída semelhante à seguinte.

sample2 test.lua
--test

Você pode brincar com todos os diferentes modos e parâmetros para conhecer a capacidade total das operações do arquivo Lua.

Necessidade de tratamento de erros

O tratamento de erros é bastante crítico, pois as operações do mundo real geralmente requerem o uso de operações complexas, que incluem operações de arquivo, transações de banco de dados e chamadas de serviço da web.

Em qualquer programação, sempre há um requisito para tratamento de erros. Os erros podem ser de dois tipos, que incluem,

  • Erros de sintaxe
  • Erros de tempo de execução

Erros de sintaxe

Os erros de sintaxe ocorrem devido ao uso impróprio de vários componentes do programa, como operadores e expressões. Um exemplo simples de erro de sintaxe é mostrado abaixo.

a == 2

Como você sabe, há uma diferença entre o uso de um único "igual a" e duplo "igual a". Usar um em vez do outro pode causar um erro. Um "igual a" refere-se à atribuição, enquanto um "igual a" duplo se refere à comparação. Da mesma forma, temos expressões e funções com suas formas predefinidas de implementação.

Outro exemplo de erro de sintaxe é mostrado abaixo -

for a= 1,10
   print(a)
end

Quando executarmos o programa acima, obteremos a seguinte saída -

lua: test2.lua:2: 'do' expected near 'print'

Os erros de sintaxe são muito mais fáceis de manipular do que os erros de tempo de execução, pois o interpretador Lua localiza o erro de forma mais clara do que no caso de erro de tempo de execução. Desde o erro acima, podemos saber facilmente que a adição de um fazer declaração perante declaração de impressão é exigida de acordo com a estrutura Lua.

Erros de tempo de execução

Em caso de erros de tempo de execução, o programa é executado com sucesso, mas pode resultar em erros de tempo de execução devido a erros na entrada ou funções mal tratadas. Um exemplo simples para mostrar o erro de tempo de execução é mostrado abaixo.

function add(a,b)
   return a+b
end

add(10)

Quando construímos o programa, ele será construído e executado com sucesso. Uma vez executado, mostra um erro de tempo de execução.

lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
	test2.lua:2: in function 'add'
	test2.lua:5: in main chunk
	[C]: ?

Este é um erro de tempo de execução, que ocorreu devido à não transmissão de duas variáveis. ob parâmetro é esperado e aqui é nulo e produz um erro.

Funções de declaração e erro

Para lidar com erros, costumamos usar duas funções - assert e error. Um exemplo simples é mostrado abaixo.

local function add(a,b)
   assert(type(a) == "number", "a is not a number")
   assert(type(b) == "number", "b is not a number")
   return a+b
end

add(10)

Quando executamos o programa acima, obteremos a seguinte saída de erro.

lua: test2.lua:3: b is not a number
stack traceback:
	[C]: in function 'assert'
	test2.lua:3: in function 'add'
	test2.lua:6: in main chunk
	[C]: ?

o error (message [, level])termina a última função protegida chamada e retorna a mensagem como a mensagem de erro. Este erro de função nunca retorna. Normalmente, o erro adiciona algumas informações sobre a posição do erro no início da mensagem. O argumento level especifica como obter a posição de erro. Com o nível 1 (o padrão), a posição de erro é onde a função de erro foi chamada. O nível 2 aponta o erro para onde a função que chamou o erro foi chamada; e assim por diante. A passagem de nível 0 evita a adição de informações de posição de erro à mensagem.

pcall e xpcall

Na programação Lua, para evitar o lançamento desses erros e o tratamento de erros, precisamos usar as funções pcall ou xpcall.

o pcall (f, arg1, ...)função chama a função solicitada no modo protegido. Se algum erro ocorrer na função f, ele não gerará um erro. Ele apenas retorna o status de erro. Um exemplo simples usando pcall é mostrado abaixo.

function myfunction ()
   n = n/nil
end

if pcall(myfunction) then
   print("Success")
else
	print("Failure")
end

Quando executamos o programa acima, obteremos a seguinte saída.

Failure

o xpcall (f, err)função chama a função solicitada e também define o manipulador de erros. Qualquer erro dentro de f não é propagado; em vez disso, xpcall detecta o erro, chama a função err com o objeto de erro original e retorna um código de status.

Um exemplo simples para xpcall é mostrado abaixo.

function myfunction ()
   n = n/nil
end

function myerrorhandler( err )
   print( "ERROR:", err )
end

status = xpcall( myfunction, myerrorhandler )
print( status)

Quando executamos o programa acima, obteremos a seguinte saída.

ERROR:	test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false

Como programador, é muito importante garantir que você cuide do tratamento de erros adequado nos programas que escreve. O uso de tratamento de erros pode garantir que condições inesperadas além das condições limites sejam tratadas sem perturbar o usuário do programa.

Lua fornece uma biblioteca de depuração, que fornece todas as funções primitivas para criarmos nosso próprio depurador. Mesmo assim, não há um depurador para Lua embutido, temos muitos depuradores para Lua, criados por vários desenvolvedores, muitos deles sendo de código aberto.

As funções disponíveis na biblioteca de depuração Lua estão listadas na tabela a seguir, juntamente com seus usos.

Sr. Não. Método e Objetivo
1

debug()

Entra no modo interativo para depuração, que permanece ativo até digitarmos apenas cont em uma linha e pressionarmos enter. O usuário pode inspecionar variáveis ​​durante este modo usando outras funções.

2

getfenv(object)

Retorna o ambiente do objeto.

3

gethook(optional thread)

Retorna as configurações de gancho atuais do thread, como três valores - a função de gancho atual, a máscara de gancho atual e a contagem de gancho atual.

4

getinfo(optional thread, function or stack level, optional flag)

Retorna uma tabela com informações sobre uma função. Você pode fornecer a função diretamente ou um número como o valor da função, o que significa que a função em execução no nível function da pilha de chamadas do thread fornecido - o nível 0 é a função atual (getinfo propriamente dito); o nível 1 é a função que chamou getinfo; e assim por diante. Se function for um número maior que o número de funções ativas, getinfo retornará nil.

5

getlocal(optional thread, stack level, local index)

Retorna o nome e o valor da variável local com índice local da função no nível da pilha. Retorna nulo se não houver variável local com o índice fornecido e gera um erro quando chamado com um nível fora do intervalo.

6

getmetatable(value)

Retorna a metatabela do objeto fornecido ou nil se não tiver uma metatabela.

7

getregistry()

Retorna a tabela de registro, uma tabela predefinida que pode ser usada por qualquer código C para armazenar qualquer valor de Lua que precise armazenar.

8

getupvalue(function, upvalue index)

Esta função retorna o nome e o valor do upvalue com o índice up da função func. A função retorna nil se não houver upvalue com o índice fornecido.

9

setfenv(function or thread or userdata, environment table)

Define o ambiente do objeto fornecido para a tabela fornecida. Retorna o objeto.

10

sethook(optional thread, hook function, hook mask string with "c" and/or "r" and/or "l", optional instruction count)

Define a função dada como um gancho. A máscara de string e o número de contagem descrevem quando o gancho será chamado. Aqui, c, r e l são chamados sempre que Lua chama, retorna e insere cada linha de código em uma função, respectivamente.

11

setlocal(optional thread, stack level, local index, value)

Atribui o valor à variável local com índice local da função no nível da pilha. A função retorna nil se não houver variável local com o índice fornecido e gera um erro quando chamada com um nível fora do intervalo. Caso contrário, ele retorna o nome da variável local.

12

setmetatable(value, metatable)

Define a metatabela para o objeto fornecido na tabela fornecida (que pode ser nula).

13

setupvalue(function, upvalue index, value)

Esta função atribui o valor ao upvalue com o índice up da função func. A função retorna nil se não houver upvalue com o índice fornecido. Caso contrário, ele retorna o nome do upvalue.

14

traceback(optional thread, optional message string, optional level argument)

Cria uma mensagem de erro estendida com um traceback.

A lista acima é a lista completa de funções de depuração em Lua e frequentemente usamos uma biblioteca que usa as funções acima e fornece depuração mais fácil. Usar essas funções e criar nosso próprio depurador é bastante complicado e não é preferível. De qualquer forma, veremos um exemplo de uso simples de funções de depuração.

function myfunction ()
   print(debug.traceback("Stack trace"))
   print(debug.getinfo(1))
   print("Stack trace end")

   return 10
end

myfunction ()
print(debug.getinfo(1))

Quando executarmos o programa acima, obteremos o rastreamento de pilha conforme mostrado abaixo.

Stack trace
stack traceback:
	test2.lua:2: in function 'myfunction'
	test2.lua:8: in main chunk
	[C]: ?
table: 0054C6C8
Stack trace end

No programa de exemplo acima, o rastreamento de pilha é impresso usando a função debug.trace disponível na biblioteca de depuração. O debug.getinfo obtém a tabela atual da função.

Depuração - Exemplo

Freqüentemente, precisamos saber as variáveis ​​locais de uma função para depuração. Para esse propósito, podemos usar getupvalue e para definir essas variáveis ​​locais, usamos setupvalue. Um exemplo simples para isso é mostrado abaixo.

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())

Quando executamos o programa acima, obteremos a seguinte saída.

1
2
index	1	k	=	1
index	2	n	=	2
11

Neste exemplo, o contador é atualizado em um cada vez que é chamado. Podemos ver o estado atual da variável local usando a função getupvalue. Em seguida, definimos a variável local com um novo valor. Aqui, n é 2 antes que a operação de definição seja chamada. Usando a função setupvalue, ele é atualizado para 10. Agora, quando chamarmos a função do contador, ele retornará 11 em vez de 3.

Tipos de depuração

  • Depuração de linha de comando
  • Depuração gráfica

Depuração de linha de comando

A depuração de linha de comando é o tipo de depuração que usa a linha de comando para depurar com a ajuda de comandos e instruções de impressão. Existem muitos depuradores de linha de comando disponíveis para Lua, dos quais alguns estão listados abaixo.

  • RemDebug- RemDebug é um depurador remoto para Lua 5.0 e 5.1. Ele permite controlar a execução de outro programa Lua remotamente, definindo pontos de interrupção e inspecionando o estado atual do programa. RemDebug também pode depurar scripts CGILua.

  • clidebugger- Um depurador de interface de linha de comando simples para Lua 5.1 escrito em Lua pura. Não depende de nada além das bibliotecas Lua 5.1 padrão. Foi inspirado no RemDebug, mas não possui instalações remotas.

  • ctrace - Uma ferramenta para rastrear chamadas de API de Lua.

  • xdbLua - Um depurador simples de linha de comando Lua para a plataforma Windows.

  • LuaInterface - Debugger- Este projeto é uma extensão do depurador para LuaInterface. Ele eleva a interface de depuração construída em Lua a um nível mais alto. A interação com o depurador é feita por eventos e chamadas de método.

  • Rldb- Este é um depurador Lua remoto via socket, disponível em Windows e Linux. Ele pode oferecer muito mais recursos do que qualquer outro existente.

  • ModDebug - Isso permite controlar a execução de outro programa Lua remotamente, definir pontos de interrupção e inspecionar o estado atual do programa.

Depuração Gráfica

A depuração gráfica está disponível com a ajuda do IDE, onde é fornecida a depuração visual de vários estados, como valores de variáveis, rastreamento de pilha e outras informações relacionadas. Há uma representação visual e controle passo a passo da execução com a ajuda de breakpoints, step into, step over e outros botões no IDE.

Existem vários depuradores gráficos para Lua e incluem o seguinte.

  • SciTE - O IDE do Windows padrão para Lua fornece vários recursos de depuração, como pontos de interrupção, etapa, etapa, etapa, variáveis ​​de observação e assim por diante.

  • Decoda - Este é um depurador gráfico com suporte para depuração remota.

  • ZeroBrane Studio- Lua IDE com depurador remoto integrado, visualização de pilha, visualização de relógio, console remoto, analisador estático e muito mais. Funciona com LuaJIT, Love2d, Moai e outros motores Lua; Windows, OSX e Linux. Código aberto.

  • akdebugger - Plugin de Debugger e editor Lua para Eclipse.

  • luaedit - Inclui depuração remota, depuração local, destaque de sintaxe, lista de propostas de conclusão, mecanismo de proposição de parâmetros, gerenciamento de breakpoint avançado (incluindo sistema de condição em pontos de interrupção e contagem de ocorrências), lista de funções, lista de variáveis ​​globais e locais, relógios, gerenciamento orientado para solução.

Lua usa gerenciamento automático de memória que usa coleta de lixo com base em certos algoritmos embutidos em Lua. Como resultado do gerenciamento automático de memória, como desenvolvedor -

  • Não há necessidade de se preocupar em alocar memória para objetos.
  • Não há necessidade de liberá-los quando não forem mais necessários, exceto para defini-lo como nulo.

Lua usa um coletor de lixo que é executado de tempos em tempos para coletar objetos mortos quando eles não estão mais acessíveis a partir do programa Lua.

Todos os objetos, incluindo tabelas, dados do usuário, funções, thread, string e assim por diante, estão sujeitos ao gerenciamento automático de memória. Lua usa marca incremental e coletor de varredura que usa dois números para controlar seus ciclos de coleta de lixo, a sabergarbage collector pause e garbage collector step multiplier. Esses valores estão em porcentagem e o valor 100 costuma ser igual a 1 internamente.

Pausa do coletor de lixo

A pausa do coletor de lixo é usada para controlar quanto tempo o coletor de lixo precisa esperar, antes; ele é chamado novamente pelo gerenciamento automático de memória da Lua. Valores menores que 100 significam que Lua não esperará pelo próximo ciclo. Da mesma forma, valores mais altos desse valor resultariam no coletor de lixo sendo lento e menos agressivo por natureza. Um valor de 200 significa que o coletor espera que a memória total em uso dobre antes de iniciar um novo ciclo. Portanto, dependendo da natureza e da velocidade do aplicativo, pode haver um requisito para alterar esse valor para obter o melhor desempenho em aplicativos Lua.

Multiplicador de etapas do coletor de lixo

Este multiplicador de passo controla a velocidade relativa do coletor de lixo em relação à alocação de memória no programa Lua. Valores de etapa maiores farão com que o coletor de lixo seja mais agressivo e também aumentará o tamanho da etapa de cada etapa incremental da coleta de lixo. Valores menores que 100 podem freqüentemente levar a evitar que o coletor de lixo não complete seu ciclo e geralmente não é preferido. O valor padrão é 200, o que significa que o coletor de lixo é executado duas vezes mais que a velocidade de alocação de memória.

Funções do coletor de lixo

Como desenvolvedores, temos algum controle sobre o gerenciamento automático de memória em Lua. Para isso, temos os seguintes métodos.

  • collectgarbage("collect") - Executa um ciclo completo de coleta de lixo.

  • collectgarbage("count") - Retorna a quantidade de memória atualmente usada pelo programa em Kilobytes.

  • collectgarbage("restart") - Se o coletor de lixo foi parado, ele o reinicia.

  • collectgarbage("setpause")- Define o valor fornecido como segundo parâmetro dividido por 100 para a variável de pausa do coletor de lixo. Seus usos são discutidos um pouco acima.

  • collectgarbage("setstepmul")- Define o valor dado como segundo parâmetro dividido por 100 para a variável multiplicadora de passo de lixo. Seus usos são discutidos um pouco acima.

  • collectgarbage("step")- Executa uma etapa da coleta de lixo. Quanto maior for o segundo argumento, maior será esta etapa. O collectgarbage retornará true se a etapa acionada foi a última etapa de um ciclo de coleta de lixo.

  • collectgarbage("stop") - Pára o coletor de lixo se estiver em execução.

Um exemplo simples usando o exemplo do coletor de lixo é mostrado abaixo.

mytable = {"apple", "orange", "banana"}

print(collectgarbage("count"))

mytable = nil

print(collectgarbage("count"))

print(collectgarbage("collect"))

print(collectgarbage("count"))

Quando executamos o programa acima, obteremos a seguinte saída. Observe que este resultado irá variar devido à diferença no tipo de sistema operacional e também ao recurso de gerenciamento automático de memória de Lua.

23.1455078125   149
23.2880859375   295
0
22.37109375     380

Você pode ver no programa acima, uma vez que a coleta de lixo é feita, ela reduz a memória usada. Mas, não é obrigatório chamar isso. Mesmo que não os chamemos, ele será executado automaticamente em um estágio posterior pelo intérprete de Lua após o período predefinido.

Obviamente, podemos alterar o comportamento do coletor de lixo usando essas funções, se necessário. Essas funções fornecem um pouco de capacidade adicional para o desenvolvedor lidar com situações complexas. Dependendo do tipo de memória necessária para o programa, você pode ou não usar este recurso. Mas é muito útil saber o uso de memória nas aplicações e verificá-lo durante a própria programação para evitar resultados indesejados após a implantação.

Introdução ao OOP

A Programação Orientada a Objetos (OOP) é ​​uma das técnicas de programação mais utilizadas na era moderna da programação. Existem várias linguagens de programação que suportam OOP, que incluem,

  • C++
  • Java
  • Objective-C
  • Smalltalk
  • C#
  • Ruby

Características do OOP

  • Class - Uma classe é um modelo extensível para criar objetos, fornecendo valores iniciais para o estado (variáveis ​​de membro) e implementações de comportamento.

  • Objects - É uma instância de classe e tem memória separada alocada para si.

  • Inheritance - É um conceito pelo qual variáveis ​​e funções de uma classe são herdadas por outra classe.

  • Encapsulation- É o processo de combinar os dados e funções dentro de uma classe. Os dados podem ser acessados ​​fora da classe com a ajuda de funções. Também é conhecido como abstração de dados.

OOP em Lua

Você pode implementar orientação a objetos em Lua com a ajuda de tabelas e funções de primeira classe de Lua. Ao colocar funções e dados relacionados em uma tabela, um objeto é formado. A herança pode ser implementada com a ajuda de meta-tabelas, fornecendo um mecanismo de pesquisa para funções (métodos) e campos não existentes em objeto (s) pai (s).

As tabelas em Lua têm características de objeto como estado e identidade que são independentes de seus valores. Dois objetos (tabelas) com o mesmo valor são objetos diferentes, enquanto um objeto pode ter valores diferentes em momentos diferentes, mas é sempre o mesmo objeto. Assim como os objetos, as tabelas têm um ciclo de vida independente de quem as criou ou de onde foram criadas.

Um exemplo do mundo real

O conceito de orientação a objetos é amplamente utilizado, mas você precisa entendê-lo claramente para obter o máximo benefício.

Vamos considerar um exemplo simples de matemática. Freqüentemente encontramos situações em que trabalhamos em diferentes formas, como círculo, retângulo e quadrado.

As formas podem ter uma área de propriedade comum. Portanto, podemos estender outras formas da forma do objeto base com a área de propriedade comum. Cada uma das formas pode ter suas próprias propriedades e funções, como um retângulo pode ter propriedades comprimento, largura, área como suas propriedades e printArea e calculArea como suas funções.

Criação de uma classe simples

Uma implementação de classe simples para um retângulo com três propriedades: área, comprimento e largura é mostrada abaixo. Também possui uma função printArea para imprimir a área calculada.

-- Meta class
Rectangle = {area = 0, length = 0, breadth = 0}

-- Derived class method new

function Rectangle:new (o,length,breadth)
   o = o or {}
   setmetatable(o, self)
   self.__index = self
   self.length = length or 0
   self.breadth = breadth or 0
   self.area = length*breadth;
   return o
end

-- Derived class method printArea

function Rectangle:printArea ()
   print("The area of Rectangle is ",self.area)
end

Criação de um objeto

Criar um objeto é o processo de alocar memória para a instância da classe. Cada um dos objetos possui sua própria memória e compartilha os dados de classe comuns.

r = Rectangle:new(nil,10,20)

Acessando Propriedades

Podemos acessar as propriedades da classe usando o operador ponto, conforme mostrado abaixo -

print(r.length)

Acessando Função de Membro

Você pode acessar uma função de membro usando o operador de dois pontos com o objeto conforme mostrado abaixo -

r:printArea()

A memória é alocada e os valores iniciais são definidos. O processo de inicialização pode ser comparado aos construtores em outras linguagens orientadas a objetos. Não é nada além de uma função que permite definir valores conforme mostrado acima.

Exemplo Completo

Vejamos um exemplo completo usando orientação a objetos em Lua.

-- 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

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

-- Creating an object
myshape = Shape:new(nil,10)

myshape:printArea()

Ao executar o programa acima, você obterá a seguinte saída.

The area is 	100

Herança em Lua

Herança é o processo de estender objetos básicos simples, como forma, a retângulos, quadrados e assim por diante. É freqüentemente usado no mundo real para compartilhar e estender as propriedades e funções básicas.

Vamos ver uma extensão de classe simples. Temos uma classe conforme mostrado abaixo.

-- 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

-- Base class method printArea

function Shape:printArea ()
   print("The area is ",self.area)
end

Podemos estender a forma para uma classe quadrada, conforme mostrado abaixo.

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

Funções básicas de sobreposição

Podemos substituir as funções da classe base que, em vez de usar a função na classe base, a classe derivada pode ter sua própria implementação, conforme mostrado abaixo -

-- Derived class method printArea

function Square:printArea ()
   print("The area of square is ",self.area)
end

Exemplo completo de herança

Podemos estender a implementação de classe simples em Lua como mostrado acima com a ajuda de outro novo método com a ajuda de meta-tabelas. Todas as variáveis ​​de membro e funções da classe base são retidas na classe derivada.

-- 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

-- 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

-- Derived class method printArea

function Square:printArea ()
   print("The area of square is ",self.area)
end

-- Creating an object
mysquare = Square:new(nil,10)
mysquare:printArea()

Rectangle = Shape:new()

-- Derived class method new

function Rectangle:new (o,length,breadth)
   o = o or Shape:new(o)
   setmetatable(o, self)
   self.__index = self
   self.area = length * breadth
   return o
end

-- Derived class method printArea

function Rectangle:printArea ()
    print("The area of Rectangle is ",self.area)
end

-- Creating an object

myrectangle = Rectangle:new(nil,10,20)
myrectangle:printArea()

Quando executarmos o programa acima, obteremos a seguinte saída -

The area is 	100
The area of square is 	100
The area of Rectangle is 	200

No exemplo acima, criamos duas classes derivadas - Retângulo e Quadrado a partir da classe base Quadrado. É possível substituir as funções da classe base na classe derivada. Neste exemplo, a classe derivada substitui a função printArea.

Lua é uma linguagem altamente flexível e frequentemente usada em várias plataformas, incluindo aplicativos da web. A comunidade Kepler que foi formada em 2004 para fornecer componentes da web de código aberto em Lua.

Mesmo assim, existem outros frameworks web usando Lua que foram desenvolvidos, estaremos focando principalmente nos componentes fornecidos pela comunidade Kepler.

Aplicativos e frameworks

  • Orbit é um framework web MVC para Lua, baseado em WSAPI.

  • WSAPI é a API que abstrai o servidor host da Web de aplicativos da Web Lua e é a base para muitos projetos.

  • Xavante é um servidor Lua Web que oferece uma interface WSAPI.

  • Sputnik é um wiki / CMS desenvolvido sobre WSAPI no Projeto Kepler usado para humor e entretenimento.

  • CGILuaoferece a criação de páginas da web LuaPages e LuaScripts, com base em WSAPI, mas não é mais compatível. Use Orbit, Sputnik ou WSAPI.

Neste tutorial, tentaremos fazer você entender o que Lua pode fazer e saber mais sobre sua instalação e uso, consulte o site kepler

Órbita

Orbit é um framework web MVC para Lua. Abandona completamente o modelo CGILua de "scripts" em favor de aplicativos, onde cada aplicativo Orbit pode caber em um único arquivo, mas você pode dividi-lo em vários arquivos se desejar.

Todas as aplicações Orbit seguem o protocolo WSAPI, por isso funcionam atualmente com Xavante, CGI e Fastcgi. Inclui um inicializador que facilita o lançamento de uma instância do Xavante para desenvolvimento.

A maneira mais fácil de instalar o Orbit é usando LuaRocks. Luarocks install orbit é o comando para instalar. Para isso, você precisa instalar o LuaRocks primeiro.

Se você não instalou todas as dependências, aqui estão os passos a serem seguidos para configurar o Orbit em ambiente Unix / Linux.

Instalando Apache

Conecte-se ao seu servidor. Instale o Apache2, seus módulos de suporte e habilite os módulos necessários do Apache2 usando -

$ sudo apt-get install apache2 libapache2-mod-fcgid libfcgi-dev build-essential $ sudo a2enmod rewrite
$ sudo a2enmod fcgid $ sudo /etc/init.d/apache2 force-reload

Instale o LuaRocks

$ sudo apt-get install luarocks

Instale WSAPI, FCGI, Orbit e Xavante

$ sudo luarocks install orbit
$ sudo luarocks install wsapi-xavante $ sudo luarocks install wsapi-fcgi

Configurando o Apache2

$ sudo raj /etc/apache2/sites-available/default

Adicione a seção a seguir abaixo da seção <Directory / var / www /> do arquivo de configuração. Se esta seção tiver um 'AllowOverride None', então você precisa alterar o 'None' para 'All' para que o arquivo .htaccess possa substituir a configuração localmente.

<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
	
</IfModule>

Reinicie o servidor para garantir que as alterações feitas tenham efeito.

Para habilitar seu aplicativo, você precisa adicionar + ExecCGI a um arquivo .htaccess na raiz do seu aplicativo Orbit - neste caso, / var / www.

Options +ExecCGI
DirectoryIndex index.ws

Exemplo Simples - Órbita

#!/usr/bin/env index.lua

-- index.lua
require"orbit"

-- 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

Agora, você deve conseguir iniciar o navegador da web. Vá para http: // localhost: 8080 / e você verá a seguinte saída -

First Page

O Orbit oferece outra opção, ou seja, o código Lua pode gerar 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())

Criação de formulários

Um exemplo de formulário simples é mostrado abaixo -

#!/usr/bin/env index.lua
require"orbit"

function wrap (inner)
   return html{ head(), body(inner) }
end

function test ()
   return wrap(form (H'table' {
      tr{td"First name",td( input{type = 'text', name='first'})},
      tr{td"Second name",td(input{type = 'text', name='second'})},
      tr{ td(input{type = 'submit', value = 'Submit!'}),
         td(input{type = 'submit',value = 'Cancel'})
      },
   }))
end

orbit.htmlify(wrap,test)

print(test())

WSAPI

Conforme mencionado anteriormente, o WSAPI atua como a base para muitos projetos e possui vários recursos incorporados. Você pode usar WSAPI e oferecer suporte às seguintes plataformas,

  • Windows
  • Sistemas baseados em UNIX

Os servidores e interfaces suportados por WSAPI incluem,

  • CGI
  • FastCGI
  • Xavante

WSAPI fornece várias bibliotecas, o que torna mais fácil para nós na programação web usando Lua. Alguns dos recursos suportados em Lua incluem,

  • Solicitar processamento
  • Buffer de saída
  • Authentication
  • Uploads de arquivos
  • Solicitar isolamento
  • Multiplexing

Um exemplo simples de WSAPI é mostrado abaixo -

#!/usr/bin/env wsapi.cgi

module(..., package.seeall)
function run(wsapi_env)
   local headers = { ["Content-type"] = "text/html" }
   
   local function hello_text()
      coroutine.yield("<html><body>")
      coroutine.yield("<p&gtHello Wsapi!</p>")
      coroutine.yield("<p&gtPATH_INFO: " .. wsapi_env.PATH_INFO .. "</p>")
      coroutine.yield("<p&gtSCRIPT_NAME: " .. wsapi_env.SCRIPT_NAME .. "</p>")
      coroutine.yield("</body></html>")
   end

   return 200, headers, coroutine.wrap(hello_text)
end

Você pode ver no código acima uma página html simples é formada e retornada. Você pode ver o uso de corrotinas que tornam possível retornar instrução por instrução para a função de chamada. Finalmente, o código de status html (200), os cabeçalhos e a página html são retornados.

Xavante

Xavante é um servidor Web Lua HTTP 1.1 que usa uma arquitetura modular baseada em manipuladores mapeados por URI. Xavante atualmente oferece,

  • Gerenciador de arquivos
  • Redirecionar manipulador
  • Manipulador WSAPI

O manipulador de arquivos é usado para arquivos gerais. O manipulador de redirecionamento permite o remapeamento de URI e o manipulador WSAPI para manipulação de aplicativos WSAPI.

Um exemplo simples é mostrado abaixo.

require "xavante.filehandler"
require "xavante.cgiluahandler"
require "xavante.redirecthandler"

-- Define here where Xavante HTTP documents scripts are located
local webDir = XAVANTE_WEB

local simplerules = {

   { -- URI remapping example
      match = "^[^%./]*/$",
      with = xavante.redirecthandler,
      params = {"index.lp"}
   }, 

   { -- 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
   },
}

Para usar hosts virtuais com o Xavante, a chamada para xavante.HTTP seria alterada para algo como o seguinte -

xavante.HTTP{
   server = {host = "*", port = 8080},
    
   defaultHost = {},
    
   virtualhosts = {
      ["www.sitename.com"] = simplerules
   }
}

Lua Web Components

  • Copas, um despachante baseado em corrotinas que podem ser usadas por servidores TCP / IP.

  • Cosmo, um mecanismo de "modelos seguros" que protege seu aplicativo de código arbitrário nos modelos.

  • Coxpcall encapsula Lua pcall e xpcall nativos com outros compatíveis com a co-rotina.

  • LuaFileSystem, uma maneira portátil de acessar a estrutura de diretório subjacente e os atributos de arquivo.

  • Rings, uma biblioteca que fornece uma maneira de criar novos estados Lua a partir de Lua.

Nota Final

Existem tantos frameworks e componentes da web baseados em Lua disponíveis para nós e de acordo com a necessidade, eles podem ser escolhidos. Existem outras estruturas da web disponíveis, que incluem o seguinte -

  • Moonstalkpermite o desenvolvimento e hospedagem eficientes de projetos baseados na web gerados dinamicamente e construídos com a linguagem Lua; de páginas básicas a aplicativos complexos.

  • Lapis, uma estrutura para construir aplicações web usando MoonScript (ou Lua) que roda dentro de uma versão customizada do Nginx chamada OpenResty.

  • Lua Server Pages, um plug-in de mecanismo de script Lua que elimina qualquer outra abordagem para o desenvolvimento da Web embarcado, oferece um atalho dramático para as páginas tradicionais do servidor C

Essas estruturas da web podem alavancar seus aplicativos da web e ajudá-lo a realizar operações poderosas.

Para operações de dados simples, podemos usar arquivos, mas, às vezes, essas operações de arquivo podem não ser eficientes, escalonáveis ​​e poderosas. Para este propósito, podemos frequentemente mudar para o uso de bancos de dados. LuaSQL é uma interface simples de Lua para vários sistemas de gerenciamento de banco de dados. LuaSQL é a biblioteca que fornece suporte para diferentes tipos de SQL. Isso inclui,

  • SQLite
  • Mysql
  • ODBC

Neste tutorial, cobriremos o manuseio de banco de dados MySQL e SQLite em Lua. Isso usa uma interface genérica para ambos e deve ser possível portar essa implementação para outros tipos de bancos de dados também. Primeiro, vamos ver como você pode fazer as operações no MySQL.

Configuração de banco de dados MySQL

Para usar os exemplos a seguir para funcionar conforme o esperado, precisamos da configuração inicial do banco de dados. As premissas estão listadas abaixo.

  • Você instalou e configurou o MySQL com usuário padrão como root e senha como '123456'.

  • Você criou um teste de banco de dados.

  • Você passou pelo tutorial do MySQL para entender os fundamentos do MySQL.

Importando MySQL

Podemos usar um simples require declaração para importar a biblioteca sqlite assumindo que sua implementação Lua foi feita corretamente.

mysql = require "luasql.mysql"

A variável mysql fornecerá acesso às funções referindo-se à tabela principal do mysql.

Configurando a conexão

Podemos configurar a conexão iniciando um ambiente MySQL e, em seguida, criando uma conexão para o ambiente. É mostrado abaixo.

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')

A conexão acima se conectará a um arquivo MySQL existente e estabelecerá a conexão com o arquivo recém-criado.

Função de execução

Existe uma função de execução simples disponível com a conexão que nos ajudará a fazer todas as operações de banco de dados de criar, inserir, excluir, atualizar e assim por diante. A sintaxe é mostrada abaixo -

conn:execute([[ 'MySQLSTATEMENT' ]])

Na sintaxe acima, precisamos garantir que conn está aberto e uma conexão MySQL existente e substituir 'MySQLSTATEMENT' pela instrução correta.

Exemplo de criação de tabela

Um exemplo simples de criação de tabela é mostrado abaixo. Ele cria uma tabela com dois parâmetros id do tipo inteiro e nome do tipo varchar.

mysql = require "luasql.mysql"

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')

print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]])
print(status,errorString )

Ao executar o programa acima, uma tabela chamada sample será criada com duas colunas, a saber, id e nome.

MySQL environment (004BB178)	MySQL connection (004BE3C8)
0	nil

Caso haja algum erro, você receberá uma instrução de erro em vez de nil. Uma declaração de erro simples é mostrada abaixo.

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

Exemplo de Inserção de Declaração

Uma instrução de inserção para o MySQL é mostrada abaixo.

conn:execute([[INSERT INTO sample values('11','Raj')]])

Exemplo de declaração de atualização

Uma instrução de atualização para o MySQL é mostrada abaixo.

conn:execute([[UPDATE sample3 SET name='John' where id ='12']])

Excluir Exemplo de Declaração

Uma instrução delete para MySQL é mostrada abaixo.

conn:execute([[DELETE from sample3 where id ='12']])

Selecione Exemplo de Declaração

No que diz respeito à instrução select, precisamos fazer um loop por cada uma das linhas e extrair os dados necessários. Uma declaração simples de seleção é mostrada abaixo.

cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   -- reusing the table of results
   row = cursor:fetch (row, "a")
end

No código acima, conn é uma conexão MySQL aberta. Com a ajuda do cursor retornado pela instrução execute, você pode percorrer a resposta da tabela e buscar os dados de seleção necessários.

Um Exemplo Completo

Um exemplo completo incluindo todas as afirmações acima é fornecido abaixo.

mysql = require "luasql.mysql"

local env  = mysql.mysql()
local conn = env:connect('test','root','123456')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]])
print(status,errorString )

status,errorString = conn:execute([[INSERT INTO sample3 values('12','Raj')]])
print(status,errorString )

cursor,errorString = conn:execute([[select * from sample3]])
print(cursor,errorString)

row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   row = cursor:fetch (row, "a")
end

-- close everything
cursor:close()
conn:close()
env:close()

Ao executar o programa acima, você obterá a seguinte saída.

MySQL environment (0037B178)	MySQL connection (0037EBA8)
0	nil
1	nil
MySQL cursor (003778A8)	nil
Id: 12, Name: Raj

Realizando transações

As transações são um mecanismo que garante a consistência dos dados. As transações devem ter as seguintes quatro propriedades -

  • Atomicity - Ou uma transação é concluída ou nada acontece.

  • Consistency - Uma transação deve começar em um estado consistente e deixar o sistema em um estado consistente.

  • Isolation - Os resultados intermediários de uma transação não são visíveis fora da transação atual.

  • Durability - Depois que uma transação foi confirmada, os efeitos são persistentes, mesmo após uma falha do sistema.

A transação começa com START TRANSACTION; e termina com a instrução de confirmação ou rollback.

Iniciar transação

Para iniciar uma transação, precisamos executar a seguinte instrução em Lua, assumindo que conn é uma conexão MySQL aberta.

conn:execute([[START TRANSACTION;]])

Transação de Rollback

Precisamos executar a seguinte instrução para reverter as alterações feitas após a execução da transação inicial.

conn:execute([[ROLLBACK;]])

Commit Transaction

Precisamos executar a seguinte instrução para confirmar as alterações feitas após a execução da transação inicial.

conn:execute([[COMMIT;]])

Sabemos sobre o MySQL na seção acima e a seguir explica sobre as operações SQL básicas. Lembre-se de transações, embora não explicadas novamente para SQLite3, mas as mesmas instruções devem funcionar para SQLite3 também.

Importando SQLite

Podemos usar uma instrução require simples para importar a biblioteca SQLite assumindo que sua implementação Lua foi feita corretamente. Durante a instalação, uma pasta libsql que contém os arquivos relacionados ao banco de dados.

sqlite3 = require "luasql.sqlite3"

A variável sqlite3 fornecerá acesso às funções referindo-se à tabela sqlite3 principal.

Configurando a conexão

Podemos configurar a conexão iniciando um ambiente SQLite e, em seguida, criando uma conexão para o ambiente. É mostrado abaixo.

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')

A conexão acima se conectará a um arquivo SQLite existente ou criará um novo arquivo SQLite e estabelecerá a conexão com o arquivo recém-criado.

Função de execução

Existe uma função de execução simples disponível com a conexão que nos ajudará a fazer todas as operações de banco de dados de criar, inserir, excluir, atualizar e assim por diante. A sintaxe é mostrada abaixo -

conn:execute([[ 'SQLite3STATEMENT' ]])

Na sintaxe acima, precisamos garantir que conn está aberto e a conexão sqlite3 existente e substituir o 'SQLite3STATEMENT' pela instrução correta.

Exemplo de criação de tabela

Um exemplo simples de criação de tabela é mostrado abaixo. Ele cria uma tabela com dois parâmetros id do tipo inteiro e nome do tipo varchar.

sqlite3 = require "luasql.sqlite3"

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )

Ao executar o programa acima, uma tabela chamada sample será criada com duas colunas, a saber, id e nome.

SQLite3 environment (003EC918)	SQLite3 connection (00421F08)
0	nil

Em caso de erro, você receberá uma declaração de erro em vez de nulo. Uma declaração de erro simples é mostrada abaixo.

LuaSQL: unrecognized token: ""'id' INTEGER, 'name' TEXT)"

Exemplo de Inserção de Declaração

Uma instrução insert para SQLite é mostrada abaixo.

conn:execute([[INSERT INTO sample values('11','Raj')]])

Selecione Exemplo de Declaração

No que diz respeito à instrução select, precisamos fazer um loop por cada uma das linhas e extrair os dados necessários. Uma declaração simples de seleção é mostrada abaixo.

cursor,errorString = conn:execute([[select * from sample]])
row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   -- reusing the table of results
   row = cursor:fetch (row, "a")
end

No código acima, conn é uma conexão sqlite3 aberta. Com a ajuda do cursor retornado pela instrução execute, você pode percorrer a resposta da tabela e buscar os dados de seleção necessários.

Um Exemplo Completo

Um exemplo completo incluindo todas as afirmações acima é fornecido abaixo.

sqlite3 = require "luasql.sqlite3"

local env  = sqlite3.sqlite3()
local conn = env:connect('mydb.sqlite')
print(env,conn)

status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]])
print(status,errorString )

status,errorString = conn:execute([[INSERT INTO sample values('1','Raj')]])
print(status,errorString )

cursor,errorString = conn:execute([[select * from sample]])
print(cursor,errorString)

row = cursor:fetch ({}, "a")

while row do
   print(string.format("Id: %s, Name: %s", row.id, row.name))
   row = cursor:fetch (row, "a")
end

-- close everything
cursor:close()
conn:close()
env:close()

Ao executar o programa acima, você obterá a seguinte saída.

SQLite3 environment (005EC918)	SQLite3 connection (005E77B0)
0	nil
1	nil
SQLite3 cursor (005E9200)	nil
Id: 1, Name: Raj

Podemos executar todas as consultas disponíveis com a ajuda desta biblioteca libsql. Então, por favor, não pare com esses exemplos. Experimente várias instruções de consulta disponíveis nos respectivos MySQL, SQLite3 e outros bancos de dados suportados em Lua.

Lua é usada em muitos motores de jogos devido à sua estrutura e sintaxe de linguagem simples. O recurso de coleta de lixo geralmente é bastante útil em jogos que consomem muita memória devido aos gráficos ricos que são usados. Alguns motores de jogo que usam Lua incluem -

  • Corona SDK
  • Gideros Mobile
  • ShiVa3D
  • Moai SDK
  • LOVE
  • CryEngine

Cada um desses motores de jogo é baseado em Lua e há um rico conjunto de APIs disponível em cada um desses motores. Veremos brevemente as capacidades de cada um.

Corona SDK

Corona SDK é um mecanismo de jogo móvel de plataforma cruzada que oferece suporte às plataformas iPhone, iPad e Android. Existe uma versão gratuita do Corona SDK que pode ser usada para pequenos jogos com recursos limitados. Você pode atualizar para outras versões quando necessário.

O Corona SDK fornece uma série de recursos que incluem o seguinte -

  • APIs de manipulação de física e colisão
  • APIs da Web e de rede
  • API Game Network
  • API de anúncios
  • API de análise
  • APIs de banco de dados e sistema de arquivos
  • APIs de criptografia e matemática
  • APIs de áudio e mídia

É mais fácil e rápido desenvolver um aplicativo usando as APIs acima, em vez de usar as APIs nativas separadamente para iOS e Android.

Gideros Mobile

Gideros fornece o SDK de plataforma cruzada para criar jogos para iOS e Android. É gratuito para uso com respingo feito com Gideros. Algumas das vantagens marcantes em Gideoros incluem, o seguinte -

  • Development IDE - Ele fornece seu próprio IDE que torna mais fácil desenvolver aplicativos Gideros.

  • Instant testing- Durante o desenvolvimento do seu jogo, ele pode ser testado em um dispositivo real através de Wifi em apenas 1 segundo. Você não precisa perder seu tempo com um processo de exportação ou implantação.

  • Plugins- Você pode facilmente estender o núcleo com plug-ins. Importe seu código existente (C, C ++, Java ou Obj-C), vincule-se a Lua e interprete-o diretamente. Dezenas de plug-ins de código aberto já foram desenvolvidos e estão prontos para uso.

  • Clean OOP approach - Gideros fornece seu próprio sistema de classes com todos os padrões OOP básicos, permitindo que você escreva um código limpo e reutilizável para qualquer um de seus jogos futuros.

  • Native speed - Desenvolvido em cima de C / C ++ e OpenGL, seu jogo roda em velocidade nativa e utiliza totalmente o poder de CPUs e GPUs por baixo.

ShiVa3D

ShiVa3D é um dos motores de jogo 3D que fornece um editor gráfico projetado para criar aplicativos e videogames para a Web, consoles e dispositivos móveis. Ele oferece suporte a várias plataformas, incluindo Windows, Mac, Linux, iOS, Android, BlackBerry, Palm OS, Wii e WebOS.

Alguns dos principais recursos incluem

  • Plugins padrão
  • API de modificação de malha
  • IDE
  • Editor integrado de terreno, oceano e animação
  • Suporte para mecanismo de física ODE
  • Controle total do mapa de luz
  • Visualização ao vivo de materiais, partículas, trilhas e HUDs
  • Suporte ao formato de troca Collada

A edição web do Shiva3d é totalmente gratuita e outras edições que você assina.

Moai SDK

Moai SDK é um mecanismo de jogo móvel de plataforma cruzada compatível com as plataformas iPhone, iPad e Android. A plataforma Moai consistia inicialmente no Moai SDK, um mecanismo de jogo de código aberto, e no Moai Cloud, uma plataforma em nuvem como serviço para hospedagem e implantação de serviços de jogo. Agora o Moai Cloud está desligado e apenas o motor de jogo está disponível.

Moai SDK é executado em várias plataformas, incluindo iOS, Android, Chrome, Windows, Mac e Linux.

AMOR

LOVE é uma estrutura que você pode usar para fazer jogos 2D. É gratuito e de código aberto. Suporta plataformas Windows, Mac OS X e Linux.

Ele fornece vários recursos que incluem,

  • API de áudio
  • API File System
  • APIs de teclado e joystick
  • API matemática
  • APIs de janela e mouse
  • API de física
  • APIs de sistema e cronômetro

CryEngine

O CryEngine é um motor de jogo desenvolvido pela desenvolvedora de jogos alemã Crytek. Ele evoluiu da geração 1 para a geração 4 e é uma solução de desenvolvimento avançada. Suporta jogos para PC, Xbox 360, PlayStation3 e WiiU.

Ele fornece vários recursos que incluem,

  • Efeitos visuais como iluminação natural e sombras suaves dinâmicas, iluminação global dinâmica em tempo real, volume de propagação de luz, sombreamento de partículas, mosaico e assim por diante.

  • Sistema de Animação de Personagens e Sistema de Individualização de Personagens.

  • Editor de Animação Esquelética Paramétrica e Animação Facial Dedicada Exclusiva

  • Sistemas de IA como malha de navegação multicamada e sistema de pontos táticos. Também oferece um sistema de edição de IA amigável para o designer.

  • Em Game Mixing & Profiling, Sons dinâmicos do sistema de som baseado em dados e música interativa e assim por diante.

  • Recursos de física como deformação processual e física avançada de corda.

Uma Nota Final

Cada um desses SDKs / frameworks de jogos tem suas próprias vantagens e desvantagens. Uma escolha adequada entre eles torna sua tarefa mais fácil e você pode se divertir melhor com ela. Portanto, antes de utilizá-lo, você precisa conhecer os requisitos do seu jogo e depois analisar o que satisfaz todas as suas necessidades e então deve utilizá-los.

As bibliotecas padrão de Lua fornecem um conjunto rico de funções que são implementadas diretamente com a API C e são embutidas na linguagem de programação Lua. Essas bibliotecas fornecem serviços dentro da linguagem de programação Lua e também serviços externos, como operações de arquivo e db.

Essas bibliotecas padrão construídas na API C oficial são fornecidas como módulos C separados. Inclui o seguinte -

  • Biblioteca básica, que inclui a sub-biblioteca de co-rotina
  • Biblioteca de Módulos
  • Manipulação de cordas
  • Manipulação de mesa
  • Biblioteca matemática
  • Entrada e saída de arquivos
  • Instalações do sistema operacional
  • Depurar instalações

Biblioteca Básica

Usamos a biblioteca básica ao longo do tutorial em vários tópicos. A tabela a seguir fornece links de páginas relacionadas e lista as funções que são abordadas em várias partes deste tutorial de Lua.

Sr. Não. Biblioteca / Método e Propósito
1

Error Handling

Inclui funções de tratamento de erros, como assert e error, conforme explicado em Lua - Tratamento de Erros .

2

Memory Management

Inclui as funções de gerenciamento automático de memória relacionadas à coleta de lixo, conforme explicado em Lua - Coleta de Lixo .

3

dofile ([filename])

Ele abre o arquivo e executa o conteúdo do arquivo como um bloco. Se nenhum parâmetro for passado, esta função executa o conteúdo da entrada padrão. Os erros serão propagados para o chamador.

4

_G

Portanto, é a variável global que mantém o ambiente global (ou seja, _G._G = _G). A própria Lua não usa essa variável.

5

getfenv ([f])

Retorna o ambiente atual em uso pela função. f pode ser uma função Lua ou um número que especifica a função naquele nível de pilha - Nível 1 é a função que chama getfenv. Se a função fornecida não for uma função Lua, ou se f for 0, getfenv retornará o ambiente global. O padrão para f é 1.

6

getmetatable (object)

Se o objeto não tiver uma metatabela, retorna nil. Caso contrário, se a metatabela do objeto possuir um campo "__metatable", retorna o valor associado. Caso contrário, retorna a metatabela do objeto fornecido.

7

ipairs (t)

Esta função busca os índices e valores das tabelas.

8

load (func [, chunkname])

Carrega um trecho usando a função func para obter seus pedaços. Cada chamada a func deve retornar uma string que se concatena com os resultados anteriores.

9

loadfile ([filename]))

Semelhante ao load, mas obtém a parte do nome do arquivo ou da entrada padrão, se nenhum nome de arquivo for fornecido.

10

loadstring (string [, chunkname])

Semelhante a load, mas obtém o pedaço da string fornecida.

11

next (table [, index])

Permite que um programa atravesse todos os campos de uma tabela. Seu primeiro argumento é uma tabela e seu segundo argumento é um índice nesta tabela. next retorna o próximo índice da tabela e seu valor associado.

12

pairs (t)

Suspende a co-rotina em execução. O parâmetro passado para este método atua como valores de retorno adicionais para a função de retomada.

13

print (...)

Suspende a co-rotina em execução. O parâmetro passado para este método atua como valores de retorno adicionais para a função de retomada.

14

rawequal (v1, v2)

Verifica se v1 é igual a v2, sem invocar nenhum metamétodo. Retorna um booleano.

15

rawget (table, index)

Obtém o valor real da tabela [índice], sem invocar nenhum metamétodo. a mesa deve ser uma mesa; índice pode ser qualquer valor.

16

rawset (table, index, value)

Define o valor real da tabela [índice] como valor, sem invocar nenhum metamétodo. table deve ser uma tabela, indexar qualquer valor diferente de nil e valorizar qualquer valor Lua. Esta função retorna uma tabela.

17

select (index, ...)

Se o índice for um número, retorna todos os argumentos após o índice do número do argumento. Caso contrário, o índice deve ser a string "#" e o select retorna o número total de argumentos extras recebidos.

18

setfenv (f, table)

Define o ambiente a ser usado pela função fornecida. f pode ser uma função Lua ou um número que especifica a função naquele nível de pilha - o Nível 1 é a função que chama setfenv. setfenv retorna a função fornecida. Como um caso especial, quando f é 0, setfenv muda o ambiente do thread em execução. Nesse caso, setfenv não retorna nenhum valor.

19

setmetatable (table, metatable)

Define a meta-tabela para a tabela fornecida. (Você não pode alterar a metatabela de outros tipos de Lua, somente de C.) Se metatabela for nil, remove a metatabela da tabela fornecida. Se a meta-tabela original tiver um campo "__metatable", ocorre um erro. Esta função retorna uma tabela.

20

tonumber (e [, base])

Tenta converter seu argumento em um número. Se o argumento já for um número ou uma string conversível em um número, tonumber retornará esse número; caso contrário, retorna nulo.

21

tostring (e)

Recebe um argumento de qualquer tipo e o converte em uma string em um formato razoável. Para controle completo de como os números são convertidos, use string.format.

22

type (v)

Retorna o tipo de seu único argumento, codificado como uma string. Os resultados possíveis desta função são "nil" (uma string, não o valor nil), "número", "string", "booleano", "tabela", "função", "thread" e "userdata".

23

unpack (list [, i [, j]])

Retorna os elementos da tabela fornecida.

24

_VERSION

Uma variável global (não uma função) que contém uma string contendo a versão atual do interpretador. O conteúdo atual desta variável é "Lua 5.1".

25

Coroutines

Inclui as funções de manipulação de co-rotina conforme explicado em Lua - Coroutines .

Biblioteca de Módulos

A biblioteca de módulos fornece as funções básicas para carregar módulos em Lua. Ele exporta uma função diretamente no ambiente global: requer. Todo o resto é exportado em um pacote de mesa. Os detalhes sobre a biblioteca de módulos são explicados no capítulo anterior Lua - tutorial Módulos .

Manipulação de cordas

Lua fornece um rico conjunto de funções de manipulação de strings. O tutorial anterior do Lua - Strings cobre isso em detalhes.

Manipulação de mesa

Lua depende de tabelas em quase todos os bits de suas operações. O tutorial anterior do Lua - Tables cobre isso em detalhes.

Entrada e saída de arquivos

Freqüentemente, precisamos de facilidade de armazenamento de dados na programação e isso é fornecido por funções de biblioteca padrão para E / S de arquivo em Lua. Isso é discutido no tutorial Lua - File I / O anterior .

Depurar instalações

Lua fornece uma biblioteca de depuração que fornece todas as funções primitivas para criarmos nosso próprio depurador. Isso é discutido em Lua - tutorial de depuração anterior .

Freqüentemente, precisamos de operações matemáticas em cálculos científicos e de engenharia e podemos aproveitar isso usando a matemática da biblioteca Lua padrão. A lista de funções disponíveis na biblioteca matemática é mostrada na tabela a seguir.

Sr. Não. Biblioteca / Método e Propósito
1

math.abs (x)

Retorna o valor absoluto de x.

2

math.acos (x)

Retorna o arco cosseno de x (em radianos).

3

math.asin (x)

Retorna o arco seno de x (em radianos).

4

math.atan (x)

Retorna o arco tangente de x (em radianos).

5

math.atan2 (y, x)

Retorna o arco tangente de y / x (em radianos), mas usa os sinais de ambos os parâmetros para encontrar o quadrante do resultado. (Ele também lida corretamente com o caso de x ser zero.)

6

math.ceil (x)

Retorna o menor inteiro maior ou igual a x.

7

math.cos (x)

Retorna o cosseno de x (considerado em radianos).

8

math.cosh (x)

Retorna o cosseno hiperbólico de x.

9

math.deg (x)

Retorna o ângulo x (dado em radianos) em graus.

10

math.exp (x)

Retorna o valor e potência x.

11

math.floor (x)

Retorna o maior inteiro menor ou igual a x.

12

math.fmod (x, y)

Retorna o restante da divisão de x por y que arredonda o quociente para zero.

13

math.frexp (x)

Retorna m e e de modo que x = m2e, e é um número inteiro e o valor absoluto de m está no intervalo [0,5, 1) (ou zero quando x é zero).

14

math.huge

O valor HUGE_VAL, um valor maior ou igual a qualquer outro valor numérico.

15

math.ldexp (m, e)

Retorna m2e (e deve ser um número inteiro).

16

math.log (x)

Retorna o logaritmo natural de x.

17

math.log10 (x)

Retorna o logaritmo de base 10 de x.

18

math.max (x, ...)

Retorna o valor máximo entre seus argumentos.

19

math.min (x, ...)

Retorna o valor mínimo entre seus argumentos.

20

math.modf (x)

Retorna dois números, a parte integral de xe a parte fracionária de x.

21

math.pi

O valor de pi.

22

math.pow (x, y)

Retorna xy. (Você também pode usar a expressão x ^ y para calcular esse valor.)

23

math.rad (x)

Retorna o ângulo x (dado em graus) em radianos.

24

math.random ([m [, n]])

Essa função é uma interface para a função geradora pseudo-aleatória simples rand fornecida por ANSI C. Quando chamada sem argumentos, retorna um número real pseudo-aleatório uniforme no intervalo [0,1). Quando chamado com um número inteiro m, math.random retorna um inteiro pseudo-aleatório uniforme no intervalo [1, m]. Quando chamado com dois números inteiros me n, math.random retorna um inteiro pseudoaleatório uniforme no intervalo [m, n].

25

math.randomseed (x)

Define x como a "semente" para o gerador pseudo-aleatório: sementes iguais produzem sequências iguais de números.

26

math.sin (x)

Retorna o seno de x (considerado em radianos).

27

math.sinh (x)

Retorna o seno hiperbólico de x.

28

math.sqrt (x)

Retorna a raiz quadrada de x. (Você também pode usar a expressão x ^ 0,5 para calcular esse valor.)

29

math.tan (x)

Retorna a tangente de x (considerada em radianos).

30

math.tanh (x)

Retorna a tangente hiperbólica de x.

Funções trigonométricas

Um exemplo simples usando a função trigonométrica é mostrado abaixo.

radianVal = math.rad(math.pi / 2)

io.write(radianVal,"\n")

-- Sin value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.sin(radianVal)),"\n")

-- Cos value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.cos(radianVal)),"\n")

-- Tan value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.tan(radianVal)),"\n")

-- Cosh value of 90(math.pi / 2) degrees
io.write(string.format("%.1f ", math.cosh(radianVal)),"\n")

-- Pi Value in degrees
io.write(math.deg(math.pi),"\n")

Quando executamos o programa acima, obteremos a seguinte saída.

0.027415567780804
0.0 
1.0 
0.0 
1.0 
180

Outras funções matemáticas comuns

Um exemplo simples usando funções matemáticas comuns é mostrado abaixo.

-- 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
io.write("Maximum in the input array is ",math.max(1,100,101,99,999),"\n")

--Min
io.write("Minimum in the input array is ",math.min(1,100,101,99,999),"\n")

Quando executamos o programa acima, obteremos a seguinte saída.

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

Os exemplos acima são apenas alguns dos exemplos comuns, podemos usar a biblioteca matemática com base em nossa necessidade, então tente usar todas as funções para ficar mais familiarizado.

Em qualquer aplicativo, geralmente é necessário para acessar as funções do nível do sistema operacional e está disponível com a biblioteca do sistema operacional. A lista de funções disponíveis está listada na tabela a seguir.

Sr. Não. Biblioteca / Método e Propósito
1

os.clock ()

Retorna uma aproximação da quantidade em segundos de tempo de CPU usado pelo programa.

2

os.date ([format [, time]])

Retorna uma string ou uma tabela contendo data e hora, formatada de acordo com o formato de string fornecido.

3

os.difftime (t2, t1)

Retorna o número de segundos do tempo t1 ao tempo t2. No POSIX, Windows e alguns outros sistemas, esse valor é exatamente t2-t1.

4

os.execute ([command])

Esta função é equivalente ao sistema de funções ANSI C. Ele passa o comando a ser executado por um shell do sistema operacional. Seu primeiro resultado é verdadeiro se o comando foi encerrado com sucesso ou nulo caso contrário.

5

os.exit ([code [, close])

Chama a saída de função ANSI C para encerrar o programa host. Se o código for verdadeiro, o status retornado será EXIT_SUCCESS; se o código for falso, o status retornado é EXIT_FAILURE; se o código for um número, o status retornado será este número.

6

os.getenv (varname)

Retorna o valor da variável de ambiente de processo varname, ou nil se a variável não está definida.

7

os.remove (filename)

Exclui o arquivo (ou diretório vazio, em sistemas POSIX) com o nome fornecido. Se essa função falhar, ela retornará nil, mais uma string que descreve o erro e o código do erro.

8

os.rename (oldname, newname)

Renomeia o arquivo ou diretório denominado oldname para newname. Se essa função falhar, ela retornará nil, mais uma string que descreve o erro e o código do erro.

9

os.setlocale (locale [, category])

Define a localidade atual do programa. locale é uma string dependente do sistema que especifica uma localidade; categoria é uma string opcional que descreve a categoria a ser alterada: "all", "collate", "ctype", "monetário", "numérico" ou "tempo"; a categoria padrão é "todos". A função retorna o nome da nova localidade ou nil se a solicitação não pode ser honrada.

10

os.time ([table])

Retorna a hora atual quando chamada sem argumentos, ou uma hora que representa a data e hora especificada pela tabela fornecida. Esta tabela deve ter campos ano, mês e dia, e pode ter campos hora (o padrão é 12), min (o padrão é 0), sec (o padrão é 0) e isdst (o padrão é nulo). Para obter uma descrição desses campos, consulte a função os.date.

11

os.tmpname ()

Retorna uma string com um nome de arquivo que pode ser usado para um arquivo temporário. O arquivo deve ser aberto explicitamente antes de seu uso e removido explicitamente quando não for mais necessário.

Funções comuns do sistema operacional

Um exemplo simples usando funções matemáticas comuns é mostrado abaixo.

-- Date with format
io.write("The date is ", os.date("%m/%d/%Y"),"\n")

-- Date and time
io.write("The date and time is ", os.date(),"\n")

-- Time
io.write("The OS time is ", os.time(),"\n")

-- Wait for some time
for i=1,1000000 do
end

-- Time since Lua started
io.write("Lua started before ", os.clock(),"\n")

Quando executamos o programa acima, obteremos uma saída semelhante à seguinte.

The date is 01/25/2014
The date and time is 01/25/14 07:38:40
The OS time is 1390615720
Lua started before 0.013

Os exemplos acima são apenas alguns dos exemplos comuns, podemos usar a biblioteca do sistema operacional com base em nossa necessidade, então tente usar todas as funções para ficar mais familiarizado. Existem funções como remove que ajuda a remover o arquivo, execute que nos ajuda a executar comandos do sistema operacional conforme explicado acima.