Primeiros Passos em Perl

Nelson Ferraz
Publicado em 19/11/2008

r7 - 19 Nov 2008 - NelsonFerraz

Primeiros Passos em Perl

Este é um pequeno tutorial de Perl, destinado a quem nao tem experiencia em programacao.

Escrevendo coisas na tela

Inicie o seu editor de textos favorito, e digite o seguinte programa. Salve-o como "print.pl":

 print "Olá, mundo!!!";

O programa é realmente simples: utiliza o comando print para imprimir um texto na tela do computador.

Execute o programa

Você pode executar o script invocando o interpretador perl manualmente:

 perl print.pl

Você deverá ver a mensagem na tela.

Experimente agora digitar o seguinte programa (print2.pl):

 print "Olá,
 mundo!!!";

Execute o programa (perl print2.pl) e veja o resultado.

Como você pode ver, a linguagem Perl é bastante flexível, e se você digitar ENTER no meio de uma linha de texto, o interpretador saberá exatamente o que fazer.

(Um dos lemas da linguagem Perl é There's More Than One Way To Do It, ou seja, existe mais de uma maneira de se fazer o que você deseja.)

Este terceiro programa faz a mesma coisa:

 print "Olá,\nmundo!!!";

O símbolo \n indica uma quebra de linha, o equivalente a digitar enter. Sempre que você quiser imprimir um texto em mais de uma linha, pode utilizar o símbolo \n.

Conversando com o usuário

No tópico anterior nós vimos como imprimir coisas na tela, utilizando o comando print.

Na maioria das vezes, porém, seu programa precisará interagir com o usuário.

Neste tópico nós veremos quais são os comandos em Perl que podem ser usados para ler o teclado, e como guardar as informações na memória.

Antes de mais nada, digite o seguinte programa e salve-o como "nome.pl":

 print "Digite o seu nome: ";
 my $nome = <>;
 print "Olá, $nome!!!";

Se o programa não contiver erros, a mensagem "Digite o seu nome:" será impressa na tela, com o cursor piscando ao lado.

A execução é interrompida na segunda linha, que faz o programa esperar que o usuário digite algo pelo teclado. Quem faz isso é o <>, conhecido em Perl como "operador diamante", que lê uma linha digitada pelo usuário. (Na verdade, o operador diamante faz muito mais do que isso, como nós veremos adiante.)

Quando o usuário pressiona ENTER, a informação digitada é associada à variável $nome, e pode então ser usada no resto do programa.

A essa altura você pode estar se perguntando: por que a variável $nome começa com um cifrão?

Variáveis Escalares

Antes de responder essa pergunta, digite mais esse programa:

 print "Digite um numero: ";
 my $x = <>;
 chomp $x;
 print "$x vezes 2 é igual a ", ($x * 2), "\n";
 print "Agora digite uma palavra: ";
 $x = <>;
 chomp $x;
 print "A palavra é '$x'!!!";

Este programa mostra que a mesma variável, $x, pode conter letras ou números.

Chamamos de variáveis de "escalares", aquelas que podem estar associadas a um valor qualquer, numérico ou alfanumérico.

Isto significa que variáveis escalares podem ser usadas para armazenar números (e com eles fazer contas) ou letras (também conhecidos como strings).

Evitando erros

Imagine que, ao digitar o programa nome.pl, você cometeu um erro de digitação:

 print "Digite o seu nome: ";
 my $nome = <>;
 print "Olá, $name!!!";

Você consegue enxergar o erro?

A variável onde guardamos o nome chama-se "$nome". Mas quando vamos imprimir seu valor, digitamos, por engano "$name".

E quando você executar o programa, ele não vai funcionar -- sem que você saiba porquê.

Felizmente perl pode te ajudar a encontrar estes erros automaticamente. Para isso, você só precisa incluir a seguinte linha no início do seu programa:

 use strict;

A diretiva use strict é muito importante, e você deve usá-la sempre, em todos os seus programas.

Quando perl encontra essa instrução, passa a exigir que todas as variáveis sejam declaradas; caso contrário ele apontará um erro. E isso é muito importante, pois, de outra forma, o erro de digitação se propagaria de maneira silenciosa.

Por isso, é importante repetir: use strict em todos os seus programas, sempre!

Voltas e mais voltas

No tópico anterior, vimos como ler uma informação digitada pelo usuário, através da entrada padrão.

Agora nós vamos ver que a entrada padrão também pode ser usada para ler a resposta de outros programas.

Em primeiro lugar, porém, precisamos ver como realizar repetições em Perl.

Laço "foreach"

Digite o seguinte programa e salve-o como "foreach.pl":

 use strict;

 for my $i (1..10) {
   print "$i\n";
 }

Ao executá-lo você deverá obter o seguinte resultado:

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10

O que aconteceu?

O comando for (ou foreach) é comum em muitas linguagens de programação. Ele simplesmente efetua um determinado número de repetições, colocando os valores numa variável ($i).

É claro que existem maneiras diferente de obter o mesmo resultado. Você pode omitir a variável $i:

 for (1..10) {
     print "$_\n";
 }

Opa! De onde surgiu essa variável "$_"???

A variável $_ é a chamada "variável padrão", que surge magicamente dentro de um loop, quando não especificamos uma variável.

Você também pode inverter a ordem da expressão:

 print "$_\n" for (1..10);

Listas

No tópico anterior, nós vimos que variáveis escalares podem armazenar qualquer valor, númerico ou alfanumérico. Mas, e se quisermos armazenar uma lista de valores?

Uma possibilidade seria utilizar diversas variáveis escalares:

 my $nome1 = "Kepler";
 my $nome2 = "Newton";
 my $nome3 = "Gauss";
 my $nome4 = "Maxwell";

 print "$nome1\n";
 print "$nome2\n";
 print "$nome3\n";
 print "$nome4\n";

Mas existe uma maneira mais inteligente, utilizando listas (ou arrays, em inglês).

Digite o seguinte programa:

 use strict;

 @nomes = ("Kepler","Newton","Gauss","Maxwell");

 print "$_\n" for @nomes;

Assim como as variáveis escalares começam com $, as listas começam sempre com @.

E, da mesma forma como nas variáveis escalares, uma lista pode misturar itens numéricos e alfanuméricos:

 @lista = ("palavra", "007", 42);

Digite agora o seguinte programa, e salve-o como "csv.pl":

 use strict;

 @lista = <>;
 print join (",",@lista);

Ao executá-lo, o programa ficará esperando que você digite alguma coisa. Digite uma palavra e pressione ENTER. Nada aconteceu?

Na verdade o programa ficará esperando que você digite várias palavras, para colocá-las em uma lista (a variável @lista). Digite mais algumas palavras e pressione Ctrl+D para indicar o término. A lista de palavras será impressa, só que separada por vírgulas.

Isto é feito pelo comando join, que serve para unir os itens de uma lista utilizando um determinado separador. Neste exemplo, os itens são separados por uma vírgula (",").

Mas por que tivemos que digitar Ctrl+D?

Como a variável @lista esperava uma lista de itens separados por ENTER, o Ctrl+D foi usado para indicar quando a lista termina. No Linux, nós podemos gerar um sinal de fim de arquivo (também conhecido como "EOF", ou end of file) através da combinação Ctrl+D. (No MS-DOS e no Windows, você usaria Ctrl+Z.)

Isto só é necessário quando digitamos uma lista manualmente. Felizmente, na maioria das vezes as listas serão "digitadas" automaticamente. A saída de um programa pode ser usada como entrada de outro. Por exemplo:

 $ ls | perl csv.pl

Neste exemplo, o comando ls simplesmente lista o conteúdo de um diretório, que é redirecionado para o nosso programa. Assim, temos uma lista de arquivos separados por vírgula!

Veja mais este exemplo:

 $ ls | sort -r | perl csv.pl

Dessa vez nós encadeamos três comandos: o ls lista os arquivos, o sort -r coloca-os em ordem reversa, e o nosso script imprime a lista separada por vígulas.

Esta é uma importante lição da "filosofia Unix":

* Escreva programas que façam apenas uma coisa mas que façam bem feito.
* Escreva programas que trabalhem juntos.
* Escreva programas que manipulem texto, pois esta é uma interface universal.

No próximo tópico veremos como um programa pode modificar seu rumo de acordo com certas condições.

Decisões

A maioria dos programas não vai simplesmente repetir os dados que foram digitados pelo usuário. Muitas vezes é necessário fazer algumas comparações e, dependendo dos resultados, tomar algumas decisões.

O comando if faz uma comparação e, dependendo do resultado, executa uma sequência de comandos. Ele funciona mais ou menos assim:




   se (expressão é verdadeira) {
      execute uma série de comandos
   }

Um exemplo simples, em Perl:




   if ($idade < 18) {
      die "Este programa é proibido para menores de 18 anos!";
   }
   # o programa continua...

O comando if não apenas pode executar uma série de comandos quando uma expressão for verdadeira, mas também quando a expressão for falsa. Para isso, usamos a expressão else ("caso contrário", em inglês):




   if ($saldo > 0) {
      print "Saldo positivo!";
   } else {
      print "Saldo negativo!";
   }

Tipos de comparação

Como você deve se lembrar, em Perl não existem diferenças entre variáveis numéricas e alfanuméricas: as mesmas variáveis podem armazenar letras e números.

E se nós quisermos comparar, por exemplo, $a=7 com $b="007"? As duas variáveis têm ou não têm o mesmo valor?

A resposta é: depende. Se compararmos literalmente, $a e $b são diferentes; se compararmos numericamente, são iguais.

Por isso, existe a distinção entre comparações numéricas e literais em Perl. Quando estivermos trabalhando com números, utilizaremos as comparações numéricas, e quando estivermos trabalhando com strings, utilizaremos as comparações literais:




   # Comparações numéricas
   if ($idade == 18) { ... }
   if ($idade > 100) { ... }

   # Comparações literais
   if ($resposta eq "s") { ... }
   if ($nome ne "Larry") { ... }

Uma questão de estilo

Assim como na Língua Portuguesa, a linguagem Perl permite inverter a ordem de uma frase.

Veja o seguinte exemplo:

   # Confirma
   print "Você deseja continuar? (s/n) ";
   my $resposta = getc();

   die "O programa termina aqui.\n" if $resposta ne "s";

   print "Vamos continuar...";

Mas lembre-se: apenas por que você pode fazer algo, não significa que deva fazer isto sempre. Por exemplo:

   print "Saldo positivo!" if $saldo > 0;
   print "Saldo negativo!" if $saldo < 0;

Como você pode ver, o código ficou repetitivo. Assim como em qualquer linguagem natural, a redundância deve ser evitada.

Apenas para concluir, vamos ver uma outra forma de se escrever uma condição, sem utilizar if, else ou unless:

   print "Saldo ", $saldo < 0 ? "negativo" : "positivo";

Com o tempo você aprenderá a usar todos estes recursos da linguagem Perl...

Hashes

Nos tópicos anteriores, nós vimos dois tipos de variáveis de Perl:

* Escalares - ex: $valor = 123;
* Arrays - ex: @lista = ('a', 'b', 'c');

O último tipo de variável é o "hash".

Um hash é semelhante a um dicionário: para cada item (ou "chave"), temos um valor correspondente.

Digite o seguinte programa:

 use strict;

 my %birthday = (
          "Johannes Kepler" => "27/12/1571",
             "Isaac Newton" => "25/12/1642",
     "Carl Friedrich Gauss" => "30/04/1777",
      "James Clerk Maxwell" => "13/06/1831"
 );

 foreach (sort keys %birthday) {
   print "$_ nasceu em $birthday{$_}.\n";
 }

Ao executar este programa, você verá a resposta:

 Carl Friedrich Gauss nasceu em 30/04/1777.
 Isaac Newton nasceu em 25/12/1642.
 James Clerk Maxwell nasceu em 13/06/1831.
 Johannes Kepler nasceu em 27/12/1571.

O hash %birthday guarda chaves e valores de acordo com a seguinte estrutura:

Chave

Valor

Carl Friedrich Gauss

30/04/1777

Isaac Newton

25/12/1642

James Clerk Maxwell

13/06/1831

Johannes Kepler

27/12/1571

Para se referir a um único item, basta utilizar a sintaxe $hash{key}, como por exemplo:

 print $birthday{"Isaac Newton"};

Dentro do laço foreach, a variável $_ guarda cada um dos nomes, e $birthday{$_}, a data de nascimento.

Expressoes Regulares

Expressões regulares são expressões usadas para analisar e manipular textos.

Em sua forma mais simples, uma expressão regular pode ser usada para verificar se um texto contém uma determinada letra, palavra, ou padrão.

Manipulando arquivos

Existem inúmeras formas de se ler arquivos em Perl.

Se você estiver escrevendo um script simples, para realizar uma tarefa rápida, pode utilizar o operador diamante (<>). Digite o programa a seguir, e salve-o com o nome de "diamond.pl":

 while ( <> ) {
     print uc($_);
 }

Experimente executar o programa, passando um arquivo-texto:

 perl diamond.pl texto.txt

Se você não tiver um arquivo texto, pode usar o próprio arquivo do programa:

 perl diamond.pl diamond.pl

O que aconteceu? O programa percorreu cada uma das linhas do arquivo, e imprimiu a linha em maiúsculas usando o comando uc.

AUTHOR

Nelson Ferraz

blog comments powered by Disqus