Do PHP Para Lua

Motivação

Foi em 1999 que, pela primeira vez, ouvi falar em Software Livre. Nessa mesma época, tive meus primeiros contatos com Linux, PHP e Javascript, que hoje são minha ferramenta de trabalho.

Somente em 2001, dois anos depois, ouvi falar na linguagem Lua. Eu trabalhava na Netage (uma empresa de informática). O Alfredo (na ocasião, colega de trabalho) mencionou, entre outras coisas, Python e Lua. De lá pra cá, todos os meus planos de aprender Python foram frustrados. Ao contrário de Lua, que reapareceu na minha vida há pouco tempo.

No início deste ano (2005), peguei algumas coisas em PHP para fazer. Como não tinha - e ainda não tenho - micro em casa, fazia muitas coisas em cyber. Como precisava de algo melhor que o Notepad, pequeno, fácil de baixar e instalar em qualquer lugar, acabei conhecendo o Scite, que hoje é meu editor de textos padrão.

Um dos principais usos de Lua é como uma linguagem embutida em outras aplicações. Entre elas, estão o elinks (um navegador em modo texto), uma porção de jogos da LucasArts e, como você já deve ter adivinhado, o SCite.

Foi assim que eu encontrei, de fato, a linguagem Lua: tentando fazer alguns scripts para o SCite. Como dizem, "a necessidade é a mãe da invenção".

Como eu estou habituado com PHP, prossigo falando de Lua pressupondo que você já conheça um pouco de PHP.

Tipagem dinâmica

Em PHP e Lua (assim como na maioria das linguagens de script), não é necessário declarar o tipo de variável. Tanto PHP como Lua fazem coerção (conversão automática entre tipos de variáveis). Assim, temos:

--Conversão de tipos em Lua
n=5
print(type(n)) --number
s="5"
print(type(s)) -- string
soma=n+s
print(soma) -- 10
print(type(soma)) --number
c = n ..s
print(c) -- string (55)
print(type(c))
<?
//Conversão de tipos em PHP
$i=5;
echo(gettype($i) ."\n"); //integer
$s="5";
echo(gettype($s) ."\n"); //string
$soma=$i+$s;
echo($soma ."\n"); //10
echo(gettype($soma . "\n")); //integer
$concatenacao =$i . $s;
echo($concatenacao ."\n"); //55
echo(gettype($concatenacao)); //string
?>

Outro exemplo:

<?
$x = '1';
$y = 2;
print($x+$y);
print("\n");
?>

Retorna 3. Mas

<?
$x = 'texto';
$y = 2;
print($x+$y);
print("\n");
?>

Retorna 2, sem informar nada.

Em Lua:

walter@walter:~/devel/waltercruz.com/artigos/dophpparalua$ lua
Lua 5.0.3  Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> ='1'+2
3
> ='texto'+2
stdin:1: attempt to perform arithmetic on a string value
stack traceback:
        stdin:1: in main chunk
        [C]: ?
>

Tables x Arrays

Tables são o principal mecanismo de estrutura de dados em Lua, semelhantes aos arrays em PHP e outras linguagens.

Porém, em Lua, o índice das tables começa em 1, não em 0, como é de praxe em quase todas as outras linguagens.

Assim, temos:

--Arrays em Lua
vogais={'a','e','i','o','u'}
print(vogais[0]) -- imprime nil, em Lua os índices começam em 1!!
print(vogais[1]) -- exibe a
print(vogais[2]) -- exibe e
print(vogais[3]) -- exibe i
print(vogais[4]) -- exibe o
print(vogais[5]) -- exibe u

Diferentes em Propósito

PHP nasceu como uma linguagem para desenvolvimento web. Lua nasceu como linguagem de descrição de dados com estruturas de controle. Ponto.

Daí já surgem algumas diferenças: o PHP tem por padrão muito mais bibliotecas que Lua. Não que Lua não tenha, mas como geralmente elas NÃO VEM instaladas com a linguagem.

No PHP, normalmente já temos instaladas bibliotecas para acesso à banco de dados, parsers de XML, etc.

A instalação padrão do Lua, pelo contrário é bem enxuta.

Existem ótimos sites para baixar bibliotecas para Lua, como o [LuaForge http://luaforge.net/] e, recentemente, o [Kepler Project http://www.keplerproject.org/].No Linux é preciso baixar o fonte, compilar e instalar. Para Windows, geralmente as bibliotecas já estão disponíveis como DLL.

Em Lua, funções são objetos de primeira classe

Em Lua, assim como em JavaScript, funções são [objetos de primeira classe http://en.wikipedia.org/wiki/First_class_function]. Junto com o escopo léxico, temos a possibilidade de usar [Closures http://en.wikipedia.org/wiki/Closure_%28computer_science%29].

Um exemplo, extraído do livro Programming in Lua (disponível em http://www.lua.org/pil/ ):

function newCounter ()
  local i = 0
    return function ()   -- anonymous function
      i = i + 1
      return i
    end
end

c1 = newCounter()
print(c1()) -- imprime 1
print(c1()) -- imprime 2
print(c1()) -- imprime 3
print(c1()) -- imprime 4
print(c1()) -- imprime 5

E, uma demonstração em javascript:

//contador com closures em javascript
function newCounter () {
  var i = 0
    return function ()  { // anonymous function
      i = i + 1
      return i
    }
}

c1 = newCounter()
alert(c1())
alert(c1())
alert(c1())
alert(c1())
alert(c1())

Como em PHP funções não são objetos de primeira classe, não é possível usar Closures em PHP. (Não de forma simples, há um exemplo em http://steike.com/PhpClosures mas é bastante complicado). A forma mais natural de se implementar um contador semelhante em PHP é com classes, conforme o código abaixo:

  function inc(){
  $this->i++;
  return $this->i;
  }
}

$x = new Counter();
print( $x->inc() );
print( $x->inc() );
print( $x->inc() );
print( $x->inc() );
print( $x->inc() );
?>

Em Lua, strings são imutáveis

Assim como a classe String em Java, strings em Lua são imutáveis. Acessar partes de uma string usando str[x] é muito próximo do que se esperaria para uma atribuição em um caractere x na string str, e como strings são imutáveis, não é possível acessar um caractere de uma string dessa maneira.

O fato de Lua implementar strings imutáveis e ter coleta de lixo gera algumas questões ao tratar de strings. Você pode ler mais sobre isso em http://www.lua.org/notes/ltn009.html .

Expressões Regulares

Em Lua, o equivalente a expressões regulares é conhecido como patterns. Segundo o Livro Programming in Lua, em http://www.lua.org/pil/20.1.html , Lua não é compatível com POSIX regexp (PCRE) por causa do tamanho: uma implementação típica de POSIX Regexp tem cerca de 4.000 linhas de código, enquanto os patterns em Lua tem cerca de 500 linhas. Incidentalmente, há uma implementação de Expressões Regulares compatíveisc om POSIX disponível em http://luacheia.lua-users.org/ .

O caractere de escape, contrariando o padrão de quase todas as outras linguagens é o %. Os barra-letra são suportados (lembrando que eles são, nesse caso porcento-letra). Segue a tabela:

meta-carectere significado
. todos os caracteres
%a letras
%c caracteres de controle
%d dígitos
%l minúsculas
%p caracteres de pontuação
%s caracteres de espaço
%u maíusculas
%w caracteres alfanuméricos
%x dígitos hexadecimais
%z o caractere com representação 0

Quem precisa de expressões regulares compatíveis com POSIX, pode se aventurar instalando o lrexlib, que pode ser baixado em: http://lrexlib.luaforge.net/ .

Interpretador Interativo

Quem conhece os interpretadores interativos do python e do ruby pode ficar um pouco confuso com o interpretador interativo de Lua.

Lua 5.0.3  Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> 5*5
stdin:1: unexpected symbol near `5'
>

A dica é: use um sinal de igual(=) antes das operações.

Lua 5.0.3  Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> =5*5
25
>
PHP 4 - A Bíblia PHP-GTK: Criando Aplicações Gráficas com PHP PHP 5: Conceitos, Programação e Integração com Banco de Dados PHP-Nuke: Integração, Administração e Desenvolvimento PHP e MySQL: Guia Introdutório PHP 5: Programação Poderosa