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>Hello Wsapi!</p>")
coroutine.yield("<p>PATH_INFO: " .. wsapi_env.PATH_INFO .. "</p>")
coroutine.yield("<p>SCRIPT_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.