palestra: Descubra o poder do Perl
Você quer aprender mais via email sobre o uso do Unix/Linux, CGI-scripts, etc.? Veja algumas dicas do boletim ViaLinuxis.
autor e speaker: Jorge Kinoshita.
apresentação: 21 de Julho de 1999 local:
Sucesu, rua Tabupuã, 627; 18:00h.
1. Introdução.
O que se espera desta palestra?
Um pensamento de quem conhecelinguagens como C, Pascal, Basic e Fortran
pode ser o seguinte:
"todas as linguagens são iguais e baseiam-se nos mesmos princípios:
todas possuem estrutras do tipo if-then-else, while, declaração
de rotinas, etc.
Para mim deve ser extremamente fácil aprender uma outra linguagem
como o Perl (pois dizem que se parece com o C).
O que me intriga (e por isso estou nesta palestra) é o seguinte:
será que o Perl possui recursos além desta programação
tradicional que me pode ser interessante? Aliás, ainda não
sei por quê, mas o Perl é muito usado para escrever CGI-scripts.
Por que não escolheram outra linguagem? O que torna o Perl uma linguagem
peculiar?
Minha visão pessoal sobre o Perl comparando com outras linguagens.
Conheço várias linguagens de programação: C,
C++, Java, JavaScript, Smalltalk, Prolog, etc. Podemos dizer que algumas
linguagens tiveram seu momento na história das linguagens apresentando
uma nova visão de como programar: entre elas destaco o Fortran
que foi uma das primeiras linguagens a apresentar o computador através
de estruturas bem padronizadas e muito mais fáceis de usar que o
Assembly, o Smalltalk que foi uma das primeiras a apresentar de
forma bem organizada a idéia de programação por objetos
e o Prolog que vê um programa como uma declaração
de uma sequencia de cláusulas que podem assumir verdadeiro e falso.
Talvez o Java que se propõe a ser uma linguagem que roda
em uma máquina virtual Java disponível em diversas plataformas
pela Sun; entretanto o Java não propõe nenhum novo paradigma
de programação.
O Perl é ao meu ver uma dessas linguagens revolucionárias
que tornam a programação muito mais rápida. Entretanto
ao contrário do Samlltalk e do Prolog que buscaram um paradigma
totalmente orientado a objetos ou um paradigama orientado à lógica,
o Perl não se preocupa em estabelecer um paradigma de programação.
A idéia de seu idealizador "Larry Wall" é a seguinte: construir
uma linguagem que seja prática de usar. Na visão de Larry
Wall pode-se fazer a mesma coisa de diversas formas e o Perl é uma
linguagem que dá muita liberdade ao programador (vide comando if
x unless == if not). Na versão corrente do Perl é possível
usar ou não programação orientada à objetos
(como o C++) (Eu pessoalmente considero o Smalltalk bem superior ao C++
mas a questão de fato não é se uma linguagem de programação
deve ser fiel ou não a um paradigma. A questão é:
será que a linguagem é confortável ao programador?
Por exemplo: em C, é possível se acessar uma posição
indevida da memória devido ao mal uso do índice de uma array,
ao mal uso de um pointer, etc. Esta preocupação é
um detalhe que desaparece nas linguagens mais modernas que se encarregam
de fazer a alocação da memória de forma conveniente
e segura.)
O que eu pessoalmente constato é que a praticidade oferecida
pelo Perl torna a programação muito mais rápida que
aquela oferecida por outras linguagens (ao meu ver, incluindo o Smalltalk
e o Prolog ).
O objetivo desta palestra é apresentar os motivos que permitem
se escrever programas em Perl de forma mais rápida que em outras
linguagens.
2. O que torna a escrita de programas em Perl mais rápida do que
em outras linguagens?
Estou listando as respostas colocando em ordem decrescente de importância.
2.1 Uso de expressões regulares.
(obs: já presente no antecessor do Perl: o AWK. Para quem está
acostumado com o Unix, lembrar do grep e do lex(flex no GNU) ).
O que são expressões regulares?
É um padrão - um formato - que se casa (match) em uma string.
O matching pode ocorrer (ser verdadeiro) ou não (ser falso) dependendo
do padrão e da string. É possível substituir as partes
que foram encaixadas por outras strings.
Exemplos:
\d+ = uma sequencia de dígitos
\w+\d = uma sequencia de letras ou dígitos (uma ou mais) seguida
de um dígito.
\w+(\d|\.) = uma sequencia de letras ou dígitos seguida de um
digito ou de um ponto.
nome:\s*.* = a palavra nome: seguida de zero ou mais espaços
(os espaços são opcionais) seguido de qualquer caracter zero
ou mais vezes.
nome:\s*(.*) = igual ao anterior, mas os parênteses servem para
capturar em $1 este valor.
etc.
\w == [a-zA-Z0-9_]
\d == [0-9]
\s == [ \r\t\n\f]
Como o Perl usa expressões regulares?
Em comandos como:
ex1: Matching
if ($linha =~ /nome:\s*(.*)/) {
$nome = $1; # extrai o nome
}
ex2: substitui uma sequencia de digitos pela palavra DIGITO (faz isto apenas
uma vez)
$linha =~ s/\d+/DIGITO/;
Para:
$linha = "asdf 234 asdf 1234 ";
após a execução do comando temos:
$linha == 'asdf DIGITO asdf 1234 '
ex3: substitui em todas as ocorrências
$linha =~ s/\d+/DIGITO/g;
resultado para $linha = "asdf 234 asdf 1234 ":
'asdf DIGITO asdf DIGITO '
ex4: dentro de um split
O Perl trabalha com listas e é extremamente simples transformar
strings em listas e vice-versa:
@gomos = split(/\s+/,$linha);
Para:
$linha = "asdf 234 asdf 1234 ";
temos:
0 'asdf'
1 234
2 'asdf'
3 1234
ex5: qual seria o resultado de
@gomos = split(/\d+/,$linha);
0 'asdf '
1 ' asdf '
2 ' '
Problema 1: Substituir um \r \n (texto no Microsoft) por apenas \n (texto
no Unix) dentro de um arquivo. Uma solução simples é
apenas retirar os \r de todas as linhas.
Para meditar: pense em como você resolveria este problema em C.
Em C você teria que:
-
abrir o arquivo de entrada,
-
Para todas as linhas do arquivo {
-
ler uma linha deste arquivo,
-
para cada carater da linha {
-
se o caracter for diferente de 0xd {
-
repassa o caracter para a saída
-
}
-
}
-
}
fechar o arquivo de saída (a menos que fosse o STDOUT).
Solução 1 em Perl:
#!/usr/bin/perl
while (<>) {
s/\r//;
print;
}
Observação: a variável $_ é usada como
default.
Solução 2 em Perl:
perl -p -e 's/\r//' $1
Problema 2: suponha um arquivo que contenha como primeira palavra uma determinada
característica e após vem o conteúdo desta característica.
Quero separar a característica e o contéudo.
Exemplos de arquivos de entrada
ex1:
nome: Jorge K.
formação: engenharia
Obs: as palavras nome: e idade podem aparecer em qualquer posição
dentro do arquivo e são tratados como palavras reservadas.
Exercício: imagine como você resolveria este problema
em C ou Pascal.
Solução em Perl:
while(<>) {
if (/\s*(\w+)/) {
$caracteristica = $1;
$conteudo = $';
}
}
Observação:
-
Em Perl não foi necessário pré definir uma char array
de um determinado valor e portanto não houve preocupação
se um arquivo texto possui uma string maior que um determinado número
de bytes.
-
Em Perl não foi necessário ficar encadeando "if s".
-
Apenas o uso de expressões regulares já torna o Perl uma
linguagem mais poderosa.
2.2. O hash
O uso de arrays é extremamente comum em linguagens convencionais:
ex: a[0], nome[4];
Uma hash é como uma array, mas ao invés do índice
ser um número é uma string.
Através de uma hash já temos então um banco de
dados simples: temos uma chave e o conteúdo da chave.
Exemplos:
$formacao{"Jorge"} = "engenheiria eletronica, mod: digital";
$turma{"Jorge"} = 1985;
Ex1: retirar elementos repetidos de um arquivo.
Imagine um arquivo que contém um nome em cada linha. Quero gerar
um arquivo de nomes mas sem nomes repetidos.
Exercício: imagine a solução em C, Pascal ou Basic.
Solução em Perl:
while (<>) {
chomp;
$lixo{$_} = 1;
}
foreach $a (keys %lixo) {
print $a . "\n";
}
hashs mapeadas em dbms.
No mundo Unix é possível se ter arquivos que vamos chamar
de "bancos de dados leves". São arquivos que associam uma chave
a um conteúdo. Um exemplo é o GDBM. É possível
mapear uma hash em um GDBM de forma extremamente simples.
Exemplo:
#!/usr/bin/perl
use GDBM_File;
dbmopen(%lixo, "lixo", 0644);
while (<>) {
chomp;
$lixo{$_} = 1;
}
foreach $a (keys %lixo) {
print $a . "\n";
}
dbmclose(%lixo);
Neste caso, é criado o arquivo lixo que pode ser manipulado posteriormente
como uma hash em outro script Perl.
2.3. A interface com o ambiente Unix
No Unix é comum que os comandos envolvam troca de strings. O perl
pode se comunicar com o Unix trocando strings.
Por exemplo: capturar uma string que vem como retorno do comando ps.
Ilustração: O comando ps no shell
[j@localhost art]$ ps
PID TTY STAT TIME COMMAND
400 1 S 0:00 (login)
401 2 S 0:00 /bin/login -- j
445 1 S 0:00 (bash)
459 1 S 0:00 (startx)
460 1 S 0:00 (xinit)
463 1 S 0:00 /usr/X11R6/bin/afterstep
474 1 S 0:00 /usr/X11R6/bin//Animate 7 4 /usr/share/afterstep/base.8bpp
0
475 1 S 0:00 /usr/X11R6/bin//Wharf 9 4 /usr/share/afterstep/base.8bpp
0 8
477 1 S 0:00 /usr/X11R6/bin//Pager 11 4 /usr/share/afterstep/base.8bpp
0
478 1 S 0:00 asclock -shape -24
492 p3 S 0:00 bash
494 1 S 0:02 emacs -geometry 128x40+0+20
574 p3 S 0:00 man perl
575 p3 S 0:00 sh -c (cd /usr/man ; (echo -e ".pl 1100i"; cat /usr/man/man1
576 p3 S 0:00 sh -c (cd /usr/man ; (echo -e ".pl 1100i"; cat /usr/man/man1
581 p3 S 0:00 /usr/bin/less -is
585 2 S 0:00 -bash
609 2 S 0:00 man perlrun
610 2 S 0:00 sh -c (cd /usr/man ; (echo -e ".pl 1100i"; cat /usr/man/man1
611 2 S 0:00 sh -c (cd /usr/man ; (echo -e ".pl 1100i"; cat /usr/man/man1
614 2 S 0:00 /usr/bin/groff -Tlatin1 -mandoc
615 2 S 0:00 /usr/bin/less -is
618 2 S 0:00 grotty
719 p0 S 0:00 bash
730 1 S 0:04 /usr/lib/netscape/netscape-communicator /usr/doc/HTML/index.
740 1 S 0:00 (netscape-commun)
749 p0 R 0:00 ps
Ex1: o comando ps dentro do Perl:
$lixo = qx/ps/;
Para quebrar $lixo em linhas basta fazer:
@lixo = split(/\n/,$lixo);
Para tratar cada uma das linhas basta fazer:
foreach $i (@lixo) {
}
e assim por diante.
2.4. Outras características.
-
não é necessário se declarar variáveis.
-
as variáveis não são tipadas. Um número pode
se comportar como um número ou como uma string dependendo do contexto.
-
uma array pode crescer on line - não é necessário
declarar uma array com um determinado tamanho de memória. Não
se tem operações de alocação dinâmica
de memória como no C (ou Pascal) tudo isto é feito de forma
transparente.
-
o Perl possui uma enorme biblioteca criada por seus fas.
-
Polemica: o Perl permite que uma mesma coisa pode ser feita de diversas
formas.
-
o Perl encara programação por objetos de uma forma simples:
pode-se criar instâncias de um pacote. Em geral, ao se criar uma
instância de um pacote também é criada uma hash (lembrar
da struct em C ou register em Pascal; não é necessário
que seja uma hash). Os métodos são funções
associadas no pacote e associadas à hash.
3. O ambiente de programação para o Perl
Sugestão:
emacs -
-
faz a identação automática
-
faz o highlight de palavras-chave
Para o debugger: O Perl já vem com o debugger.
4. O uso mais conhecido do Perl: contrução de CGI-scripts
Em geral, ao preencher um formulário na internet, um programa de
computador do lado do servidor monta uma página como resposta a
este formulário e o envia ao cliente. Este programa do lado do servidor
que recebe as informações do cliente, processa-as e monta
a página de retorno é um CGI-script. Um CGI-script pode ser
escrito em qualquer linguagem, mas o Perl é a linguagem preferida
porque pode facilmente extrair os dados do formulário preenchido
e gerar uma página de retorno através da manipulação
de strings. Por exemplo, o usuário preenche as palavras chave em
um sistema de busca e clica o botão submit. O script CGI deve retirar
Que características tornam o Perl interessante para a escrita
de CGI-scrits?
As mais conhecidas:
-
o uso de expressões regulares.
-
máquinas Unix são comumente usadas como servidores web e
o Perl possui uma boa interface com o Unix.
Exemplo de um script:
#!/usr/bin/perl -w
use CGI qw(:standard);
my $nome = param("nome");
print header() . start_html("Exemplo de um CGI") . h1("Exemplo de CGI")
;
if ($nome) {
print p("boa tarde $nome");
} else {
print hr() . start_form();
print p("digite seu nome: " . textfield("nome", ""));
print end_form() . hr();
}
Veja a entrada
e saída
do ponto de vista do usuário. Obs: Aqui tenho apenas os HTML de
entrada e saida porque nao tenho acesso ao diretorio /home/httpd/cgi-bin
desta maquina. Ou seja, voce nao estah vendo o formulario sendo processado.
5. Como aprender e usar o Perl?
-
recomendo os livros da O'Reilly como "PERL" de Larry Wall (o livro do camelo)
ou Learning Perl de Tom Christiansen (o livro da lhama).
-
ministro cursos de Perl e dou consultoria nesta área (construção
de sites, uso de Java/JavaScript para o cliente).
6. Conclusão.
-
a linguagem Perl possui características que tornam uma linguagem
poderosa: o conceito de hash e a manipulação de strings não
são comumente vistas em outras linguagens.
-
Dadas suas caracterísitcas o Perl tem sido muito usado em scripts-cgi.
-
as facilidades oferecidas pelo Perl se encaixam em muitos outros tipos
de programas além de CGI-scripts. Por exemplo, em programas que
envolvem linguística computacional onde é necessário
fazer manipulações de strigs.
-
o título da palestra que eu sugeri era: Perl, além dos CGI-scripts.
Espero ter mostrado que o caso do CGI-scripts é apenas uma das inúmeras
possiveis aplicações do Perl. Outros exemplos envolvem: geração
de relatórios, programas que traduzem uma determidado comando em
outro, etc.
Nesta palestra, você deve ter aprendido:
-
que o uso de expressões regulares permitem a construção
rápida de programas.
-
que uma hash é um simples estrutura e já pode ser usada para
se criar bancos de dados.
-
como o Perl é usado em um CGI-script.