Você está na página 1de 76

Manual Conciso de Perl

Jos A. Soares Augusto e


Prof. Auxiliar, Sec. Electrnica, DEEC, Instituto Superior Tcnico, Lisboa, PORTUGAL o e Investigador, INESC-ID, Lisboa, PORTUGAL

Verso 2.0.0, Outubro de 2001 a

Conte do u
1 Introduo ca 1.1 1.2 Instalaao e invocaao do Perl c c . . . . . . . . . . . . . . . . . . . . . . . . . A quem se dedica este Manual? . . . . . . . . . . . . . . . . . . . . . . . . . 3 5 7 8 8 9 12 14 14 15 17 19 21 22 24 24 25 25 26 29 30 31 32 Notas sobre referncias . . . . . . . . . . . . . . . . . . . . . . . . . . e Strings, listas e expresses regulares. Interpolaao . . . . . . . . . . o c Operadores aplicveis a escalares . . . . . . . . . . . . . . . . . . . . a Funoes matemticas . . . . . . . . . . . . . . . . . . . . . . . . . . . c a Operadores de teste a cheiros . . . . . . . . . . . . . . . . . . . . . Tpicos mais avanados na utilizaao de <...> . . . . . . . . . . . . o c c Outras funoes de acesso a cheiros . . . . . . . . . . . . . . . . . . c

2 Breve digresso no Perl a 2.1 2.2 2.3 Invocaao do interpretador . . . . . . . . . . . . . . . . . . . . . . . . . . . c Particularidades do Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Manpages do Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3 Variveis a 3.1 Escalares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.1.1 3.1.2 3.1.3 3.1.4 3.2 3.2.1 3.2.2 3.2.3 3.3 3.4 3.5 3.6 3.7

Filehandles (referncias para cheiros) . . . . . . . . . . . . . . . . . . . . e

Dirhandles (referncias para directorias) . . . . . . . . . . . . . . . . . . . . e Arrays (ou vectores ou listas) . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1 Converso entre arrays e strings . . . . . . . . . . . . . . . . . . . a Contexto escalar e contexto de lista . . . . . . . . . . . . . . . . . . . . . . . Programaao funcional: grep e map . . . . . . . . . . . . . . . . . . . . . . . c Hashes (dicionrios) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a 1

3.8

Variveis especiais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a

33 39 39 41 43 45 45 46 49 50 51 52 53 56 58 61 61 61 66 66 67 69 70 71 73 76

4 Referncias: princ e pios bsicos a 4.1 4.2 4.3 Criaao de referncias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c e Utilizaao de referncias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c e Referncias Simblicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e o

5 Processamento condicional e iterativo 5.1 5.2 5.3 5.4 Selecao e processamento condicional . . . . . . . . . . . . . . . . . . . . . . c Iteraao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . c Modicadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6 Subprogramas, subrotinas ou funoes c 6.1 6.2 Variveis locais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a Passagem de argumentos para subrotinas . . . . . . . . . . . . . . . . . . .

7 Execuo de cdigo em run-time: eval e require ca o 8 Expresses regulares (regexes) o 8.1 8.2 8.3 Sintaxe ampliada (extended) de expresses regulares . . . . . . . . . . . . o Regras aplicveis em expresses regulares . . . . . . . . . . . . . . . . . . . a o Pesquisa, substituiao e transliteraao . . . . . . . . . . . . . . . . . . . . . c c

9 Manipulao de arrays de arrays em Perl ca 9.1 9.2 9.3 9.4 9.5 Declaraao e acesso a arrays de arrays (AoAs) . . . . . . . . . . . . . . . . . c Criaao dinmica de AoAs . . . . . . . . . . . . . . . . . . . . . . . . . . . . c a Acesso e impresso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a Fatias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arrays de hashes, hashes de hashes, etc... . . . . . . . . . . . . . . . . . . .

10 Outras Funoes em Perl c 11 Concluso a

Introduo ca

O Perl a mais conhecida e utilizada linguagem de scripting (LdS) na actualidade. e Pode ser instalada em quase todas as plataformas e sistemas operativos (SOs) existentes em mais do que o Java! e muito verstil. Alm do mais, distribu como freeware e a e e da e h milhares de sites na Internet com contedo relacionado com o Perl incluindo, por a u exemplo, milhares de scripts CGI para utilizar em pginas no World Wide Web a (WWW). Tambm existem dispon e veis centenas de mdulos (ou bibliotecas) destinados o `s mais variadas tarefas de programaao (e.g., funoes matemticas, a c c a compresso/descompresso de arquivos, cifragem de informaao, geraao/interpretaao de a a c c c cheiros HTML e XML, comunicaao, acesso a bases de dados, etc...) c O site ocial do Perl http://www.perl.com e contm muitos links para outras fontes de e e informaao uteis. Existe um arquivo, denominado CPAN (Comprehensive Perl Archive c Network), que tem espelhos (mirrors) um pouco por por todo o mundo (incluindo um muito lento no IST!), de onde podem ser descarregados os principais mdulos de extenso o a dispon veis para a linguagem. Os directrios da rea da programaao dos motores de o a c pesquisa (e.g., do Google) contm centenas de links para sites relacionados com o Perl. e O Perl partilha as qualidades, defeitos, vantagens e desvantagens de outras LdS, das quais destacamos o python, o ruby, o Tcl/Tk e, em menor grau por ser muito menos verstil, o a awk (ou a sua verso GNU, o gawk). O Perl uma linguagem a e semi-interpretada/semi-compilada, embora ` luz dos tradicionais conceitos de a compilaao/interpretaao seja aparentemente interpretada, o que permite c c programar-executar consecutivamente, pois no existem as fases intermdias (e lentas) a e de compilaao e de ligaao (link) dos programas: aps escrever um script em Perl com c c o um simples editor de texto (e.g. o bsico Notepad ) pode-se, imediatamente, execut-lo e a a observar o resultado ou a mensagem de erro 8-). H outras linguagens que usam o Perl como modelo e que partilham com ele alguma da a sintaxe. A linguagem ruby (www.ruby-lang.org) um bom exemplo, sendo a sua e caracter stica mais notria o facto de ser inerentemente uma liguagem orientada para o objectos, implementando herana, polimorsmo, sobrecarga (overload) de operadores, c etc: o ruby pode ser descrito sumariamente como um perl orientado para objectos. Outra linguagem aparentada com o Perl o PHP, largamente utilizado em servidores Web e em tarefas de server-side-scripting associado, por exemplo, a bases de dados como seja a mySQL. O Perl (como as restantes LdSs) permite uma ecincia de programaao, e c comparativamente a linguagens compiladas, estimada entre 2 e 10 vezes maior, quer em tempo de desenvolvimento, quer em nmero de linhas de cdigo escritas. O autor, que u o utiliza regularmente h largos anos o Perl (e tambm o awk e o python), e que j escreveu a e a uns largos milhares de linhas de cdigo nestas linguagens, estima que a ecincia de o e programaao melhorada aproximadamente de um factor de 5, comparativamente ao C. c e Rera-se que o python a segunda LdS mais divulgada, a seguir ao Perl. Tem a seu favor e o facto de ter evolu de uma forma mais organizada que o Perl e de ter, possivelmente, do uma documentaao de melhor qualidade. Alm disso, mais fcil ler e entender scripts c e e a em python do que em Perl, o que implica que mais fcil manter cdigo escrito em e a o python. Porm, o facto de o Perl ter sido a LdS que acompanhou o crescimento da Web e e de ter um leque de comandos mais sucintos e poderosos (embora cr pticos...), leva a que o 3

nmero de seguidores do Perl ainda exceda largamente os apologistas do python. No se u a esquea que h quem defenda com mais fundamentalismo a sua linguagem de c a programaao preferida do que a religio que pratica ou, mesmo, do que o clube de futebol c a de que adepto B-). e Encaradas at h pouco tempo como parentes pobres da programaao sria, talvez por e a c e serem desenvolvidas por programadores voluntrios e no terem companhias de renome a a a suport-las, actualmente as LdSs so respeitadas e adoptadas por grandes organizaoes. a a c Por um lado, o seu desenvolvimento e evoluao j estabilizaram e, por outro, apesar de c a serem quase sempre software distribu em regime livre (freeware), comeou a haver do c suporte comercial por parte de companhias que efectuam formaao, prestam apoio tcnico c e e instalam sistemas ` la carte optimizados para determinadas funoes. Por exemplo, a a c companhia ActiveState que mantm a distribuiao ocial do Perl para as vrias verses e c a o do Microsoft Windows e, tambm, do python e do Tcl/Tk, fortemente nanciada pela e e Microsoft e emprega um largo nmero de programadores que foram muito importantes na u fase de desenvolvimento e divulgaao das LdSs. c O mote do Perl Theres more than one way to do it(TMTOWTDI). De facto, para e realizar uma tarefa em Perl h sempre muitas opoes! Cada programador dever, em a c a princ pio, escolher a melhor (relativamente ao parmetro de desempenho pretendido) das a opoes que domina 8-). Por exemplo, embora se possa realizar programaao orientada c c para objectos (OOP) em Perl, virtualmente 100% da funcionalidade da linguagem est a dispon mesmo sem enveredar por aquela metodologia de programaao. vel c Neste manual expe-se o ncleo da linguagem de programaao Perl, tentando realar as o u c c vantagens da linguagem no que respeita ` ecincia e ` rapidez da escrita de programas. a e a O Perl capaz de agradar a uma vasta gama de programadores, pois justica o mote e TMTOWTDI: mesmo programadores inexperientes podem retirar, rapidamente, aps o dominar as construoes bsicas da linguagem, benef c a cios da poderosa infraestrutura de processamento que o Perl disponibiliza. Para alm de explicar os fundamentos do Perl e alguns dos seus aspectos peculiares (e.g., e a diferente interpretaao de expresses em contexto escalar e em contexto de lista) c o frequentemente recorrendo a blocos de cdigo m o nimos, expomos sucintamente as principais funoes e operadores do Perl. Na abordagem de alguns tpicos, segue-se de c o perto as exposioes dos manuais. A profundidade da exposiao varia: por exemplo, a c c relaao entre referncias e estruturas de dados complexas e as expresses regulares, so c e o a alguns dos tpicos tratados com detalhe. Em contrapartida, o modelo de orientaao para o c objectos que poss utilizar no Perl bastante complexo (de certa maneira, foi e vel e enxertado na linguagem) e dispensvel numa primeira abordagem. e a Uma grande parte da popularidade do Perl, do python e do ruby,deve-se ` existncia de a e mdulos (ou bibliotecas) grtis que permitem realizar tarefas espec o a cas (funoes c matemticas especiais, parsing de HTML e de XML, comunicaoes, acesso a bases de a c dados, etc...). Estes mdulos so normalmente mantidos por voluntrios, mas quer a o a a correcao de bugs, quer o seu melhoramento, so normalmente muito rpidos, pelo que c a a muita gente os usa. Neste documento imposs referi-los a todos, remetendo-se os e vel interessados em realizar tarefas espec cas ` consulta do CPAN, no caso do Perl, ou dos a sites www.python.org e www.ruby-lang.org, no caso do python e do ruby, que listam milhares de mdulos e sub-mdulos destinados `s mais diversas aplicaoes. o o a c

1.1

Instalao e invocao do Perl ca ca

Vai discutir-se, brevemente, a instalaao e a invocaao do Perl em ambientes Windows c c (Windows95/98/NT/2000/Millenium) e Unix (ou as suas variantes: Linux, Solaris, Aix, Hp-Ux,...). Perdoem-me os fs do Mac (principalmente estes...) mas nunca utilizei Perl a em ambiente Macintosh. Fiquem, porm, a saber que existe imensa informaao sobre a e c utilizaao do Perl em Mac, incluindo obviamente binrios para instalaao. O tamanho c a c dos binrios da verso actual (Perl 5.8.0) ronda os 11,5 megabytes, variando um pouco a a consoante o sistema operativo (SO). A instalaao do Perl em Unix (ou em SOs semelhantes, como o Linux...) feita numa de c e trs formas: ou existe uma verso do Perl inclu no sistema operativo (o que verdade e a da e em mais de 90% dos casos...), ou existem binrios dispon a veis para a arquitectura, ou e compilado o cdigo fonte (code source) com o gcc ou outro compilador de C. o Normalmente, no h grandes problemas neste processo, tendo-se apenas de seleccionar os a a mdulos que se pretende compilar. Estes mdulos so, em geral, escritos numa mistura de o o a Perl e de C. Em DOS/Windows, at h 3 ou 4 anos era dif utilizar cabalmente o Perl. e a cil Actualmente, este j no o caso. A melhor opao dispon consiste em utilizar a a a e c vel distribuiao ocial do Perl para Windows, mantida pela companhia ActiveState c (http://www.activestate.com). Esta distribuiao utiliza o formato de instalaao .msi c c da Microsoft (para Windows95/98 dever ser feita uma instalaao prvia do instalador da a c e Microsoft que se encontra dispon no site da ActiveState ou, obviamente, no site da vel Microsoft). Diga-se que a ActiveState nanciada pela Microsoft B-) e que o Perl e o e python vo ser inclu a dos na prxima verso do Visual-Studio da Microsoft. Aquela o a distribuiao ocial inclui mdulos espec c o cos para Windows que permitem aceder a aplicaoes da Microsoft (Word, Excel, Access,...) e de outras companhias de software a c partir do Perl. Existe tambm uma distribuiao de binrios para Windows, compilada com VisualC, e c a denominada indigoperl. Esta distribuiao mantida pela companhia Indigostar c e (http://www.indigostar.com) e tem a particularidade de incluir o servidor Apache compilado com vrios mdulos, de onde se destaca o modperl que permite utilizar o Perl a o como linguagem de server-side-scripting (o interpretador executado concorrentemente e com o servidor, o que acelera a execuao de scripts em Perl embebidos em pginas de c a HTML). Ainda em Windows, poder ser utilizado o VisualC (5 ou 6) para compilar as sources do a Perl ou, em alternativa, o sistema Cygwin (um port do ambiente Unix para Windows que inclui ferramentas como o make e o gcc). Existem binrios do Perl j pr-compilados a a e com o Cygwin. Recentemente, a Siemens disponibilizou ainda outra distribuiao c compilada do Perl. O CPAN divulga os links para estes e outros binrios. a Vai-se enumerar as vantagens e as desvantagens associadas `s LdS. As desvantagens das a linguagens de scripting, relativamente `s linguagens compiladas so: a a execuao de scripts mais lenta do que programas compilados (dependendo das c tarefas, entre 2 e 20 vezes) as LdSs tm sofrido uma evoluao muito rpida, por vezes com ligeiras e c a incompatibilidades entre verses (embora, seja dita a verdade, se tente sempre o 5

preservar a retro-compatibilidade) muitas LdSs no exigem a declaraao das variveis, o que permite programar a c a rapidamente; porm, os interpretadores no alertam para erros que as linguagens e a compiladas, onde a declaraao de variveis obrigatria, alertam c a e o devido `s poderosas instruoes dispon a c veis nas LdS, a leitura e compreenso dos a programas por vezes dif (o Perl o principal suspeito neste e cil e tem...), o que exige do programador a disciplina necessria ` escrita de boa documentaao. a a c Por outro lado, as vantagens das linguagens de scripting so: a ser ` borla! a permitir desenvolver rapidamente programas, o que enche de orgulho os programadores. A disponibilidade de uma grande quantidade de mdulos e o bibliotecas, organizados, sujeitos a manutenao constante e bem documentados, c ajuda ` sua divulgaao a c dispr de instruoes sintticas e poderosas para processar texto (procurar, o c e substituir, ordenar, separar,...) e suportam sintaxes complexas de expresses o regulares quase todas suportam OOP, sendo as mais evolu das neste dom nio o ruby e o python. Muitas incluem poderosas instruoes de programaao funcional (ltros, c c iteradores,...) esto dispon a veis para muitas plataformas, sendo a compatibilidade entre scripts escritos em vrias plataformas quase de 100% (descontando, obviamente, as tarefas a espec cas a cada SO) permitem programar extenses em C e algumas (o python, por exemplo) tm o e interpretadores escritos em Java e a possibilidade de utilizar a grande quantidade de classes de Java dispon veis a documentao dispon para as linguagens excelente. Neste ponto ca vel e destacam-se o python e o Perl. A documentaao do awk boa, mas a linguagem c e e relativamente pouco potente. O ruby uma linguagem que se desenvolveu durante e muito tempo quase exclusivamente no Japo, pelo que a sua documentaao em a c ingls era apenas razovel: se souber ler Japons parabns B-). No entanto, foram e a e e publicados recentemente alguns excelentes livros de ruby, em Ingls. Um desses e livros est dispon on-line. a vel fazem automaticamente a gesto de memria dinmica: reservam e libertam a o a memria quando as variveis so criadas ou eliminadas. Lembre-se que a gesto de o a a a memria uma das grandes causas de bugs em C. o e Segundo o criador do Perl, Larry Wall, esta linguagem visa suprir os trs principais e defeitos do programador t pico: laziness, impatience, and hubris(i.e., preguia, c impacincia e mania !). Leia a B e blia do Perl, o livro de Larry Wall, Tom Christiansen e Randall Schwartz, Programming Perl, da OReilly & Associates, para descobrir porqu! e 6

1.2

A quem se dedica este Manual?

Aos alunos de SVTCE, obviamente, 8-). O Perl excelente para processar o tipo de e cheiros associado a ferramentas de simulaao e de teste de circuitos elctricos, que so c e a habitualmente simples cheiros de texto. No se presume que o leitor vai aprender os fundamentos de programaao com este a c manual. No entanto, quem souber programar razoavelmente numa outra linguagem decerto no ter diculdade em seguir, at ao m, este texto. Nas partes menos claras ou a a e omissas (o que feito propositadamente, devido ` escassez de tempo), sugere-se a e a consulta de um bom livro de Perl ou dos manuais que so instalados juntamente com os a cheiros executveis da linguagem. a

2
2.1

Breve digresso no Perl a


Invocao do interpretador ca

A execuao em Unix de um programa em Perl denominado, por exemplo, script.pl c e feita da seguinte forma
unix> perl script.pl arg1 arg2 ...

onde unix> representa a linha de escrita de comandos (ou consola de comandos) em Unix e arg1, arg2,... so os (eventuais) argumentos passados para o programa. O executvel a a do Perl dever estar na directoria /bin, /usr/bin, ou noutra em que o SO a encontre a (i.e., no path). Alternativamente, se script.pl fr tornado executvel com o comando o a
unix> chmod +x script.pl

e a linha inicial do programa script.pl fr o


#!/usr/bin/perl

(supondo que o Perl se encontra na directoria /usr/bin) ele executado com e


unix> script.pl [arg1 arg2 ...]

Em DOS/Windows95/98 tem de se fazer obrigatoriamente


dos> perl script.pl arg1 arg2 ...

embora em WindowsNT/2000 se possa tornar executveis scripts em Perl atravs do a e registo (pelo administrador do sistema) do suxo .pl como sendo executado com o progama perl.exe (no sei os detalhes todos, pois no uso WindowsNT/2000). a a Em algumas distribuioes para Windows95/98 existe um programa pl2bat.bat c (habitualmente na directoria onde se encontra o perl.exe) que gera, a partir de script.pl, um cheiro script.bat que pode ser invocado como
dos> script arg1 arg2 ...

O Perl dispe de uma quantidade impressionante de pginas de manual (manpages). Em o a Unix acede-se a esses manuais com
unix> man perl

e em Windows com o utilitrio perldoc.bat fazendo a


dos> perldoc perl

A documentaao encontra-se subdividida em sub-manuais cuja descriao sumria se c c a encontra na pgina principal intitulada perl. Na distribuiao para Windows os manuais a c esto dispon a veis em formato .html. O comando perl tem vrios interruptores (ou opoes): por exemplo a c
perl -w script.pl arg1 arg2 ...

executa script.pl e emite avisos (warnings, da -w) sobre, por exemplo, a utilizaao de c valores de variveis no inicializadas. Fazendo perl -v obtm-se a verso de Perl a a e a instalada. Pode-se fazer um pequeno script na linha de comando com o interruptor -e: por exemplo,
perl -e "print @ARGV;"a b c d 1245

imprime abcd1245, pois o vector @ARGV contm os argumentos fornecidos ao script (neste e caso a b c d 1245). Recomenda-se vivamente a utilizao do interruptor -w, pelo menos na fase de ca 8

desenvolvimento dos programas.

2.2

Particularidades do Perl

Vejamos alguns pormenores bsicos da programaao em Perl. a c Basta um editor de texto no formatado freeware (e.g. Notepad, Wordpad, a Editpad, NotetabLight) para escrever um programa em Perl. Porm, pode utilizar-se e editores potentes como o emacs e o vi, ou mesmo IDEs comerciais. Um comentrio em Perl o texto escrito entre # e o m de uma linha. Existem a e formas mais complexas de comentar programas (veja plain old documentation, ou POD, na manpage perlpod). Uma instruao termina sempre com ; excepto quando se tratar de um bloco de c instruoes, limitado por { e por }, ou da ultima instruao de um bloco que no c c a necessitam de terminar com ; . Existem apenas trs tipos (importantes) de variveis em Perl, completamente e a especicados pelo caracter com que comea a designaao da varivel: c c a as variveis escalares comeam obrigatoriamente por $. Estas variveis a c a podem conter nmeros, strings ou referncias (i.e., apontadores) u e os arrays (vectores) comeam obrigatoriamente por @. O primeiro c ndice de um array zero (como no C). Como cada elemento de um array escalar, e e para os referir inicia-se o nome por $ (veja os exemplos mais abaixo) os hashes (ou arrays associativos, ou dicionrios) comeam a c obrigatoriamente por %. Estas variveis so colecoes indexadas por strings, a a c enquanto que os arrays so indexados por inteiros. Os hashes so de extrema a a utilidade prtica na implementaao de estruturas de dados complexas e de a c algoritmos. Os nomes de subprogramas (ou subrotinas, ou funoes) so (quase sempre...) c a invocados com um & no in cio. Assim, num mesmo programa em Perl podem existir, sem qualquer conito, os nomes $nome, @nome, %nome e &nome. Representam entidades diferentes entre si! Ainda pode existir a entidade *nome, denominada typeglob, que uma referncia e e genrica para qualquer das anteriores variveis: os typeglobs eram fundamentais no e a perl4 que no possu referncias, mas so pouco importantes no actual perl5. a a e a O tipo caligrco das variveis importante: o Perl diferencia mai sculas e a a e u min sculas. Por exemplo, $xpto diferente de $Xpto. u e Existem dezenas de variveis pr-denidas: quase todas so uma combinaao do a e a c caracter de deniao do tipo da varivel ($, @ ou %) com um ou mais caracteres no c a a alfabticos (e.g. $", @ , ...). A memorizaao destas variveis uma das grandes e c a e dores de cabea para os iniciados no Perl. Muito importantes so $ e @ , pois so c a a utilizadas, por defeito, por muitas funoes quando estas so invocadas sem um c a argumento. 9

No obrigatria a declarao de variveis em Perl a no ser que, no in do a e o ca a a cio programa, se use o pragma (ou directiva para o interpretador) use strict;. Por exemplo, a instruao $iarr[1000]=1999; implicitamente declara e cria o array c $iarr, e coloca o valor 1999 na posiao 1001 (o in dos arrays na posiao 0). c cio e c A escrita de subprogramas (feita segundo o padro sub subnome { instruoes }, a c~ onde subnome a sua denominaao) pode aparecer em qualquer parte do cheiro de e c cdigo; o interpretador faz duas passagens e assim permite a deniao diferida de o c subrotinas. Existem vrios tipos de strings: as escritas entre aspas "...." e as escritas entre a plicas .... so as mais importantes. Nas primeiras, feita interpolaao de a e c variveis escalares, de arrays e de caracteres escapados (por exemplo \n indica o a m da linha e \t um tab), enquanto que nas segundas no feita qualquer e a e interpolaao. Por interpolaao entende-se a substituiao da varivel embebida no c c c a texto da string. Veja-se o seguinte exemplo:
$foo = Bobi; print "$foo fugiu!\n"; print $foo fugiu!\n; # imprime Bobi fugiu! e termina a linha # imprime $foo fugiu!\n e n~o muda de linha a

Existem formas alternativas de escrever strings: ... e "..."so apenas duas a delas. Igualando uma varivel escalar a uma string-comando (string contendo um comando a de sistema vlido) escrita entre (acentos graves), o comando executado e o a e resultado atribu ` varivel. E feita interpolaao de variveis nestas strings. Por e do a a c a exemplo;
$command = dir; print $command; # executa dir e guarda o resultado

equivalente a executar o comando dir (em DOS/Windows). e Para executar um comando no sistema tambm se pode usar system. Por exemplo, e se se quiser apagar o cheiro xpto.txt na actual directoria de trabalho executa-se system del xpto.txt; em DOS (ou system rm xpto.txt; em Unix). O Perl liberal na sintaxe de invocaao de funoes: por exemplo, para calcular o e c c seno de $num (em radianos) pode usar-se sin($num); ou sin $num; (os parntesis e devero ser utilizados sempre que houver dvidas na precedncia de operaoes). a u e c Uma das tarefas rotineiras onde o Perl brilha na leitura, interpretaao e e c transformaao de cheiros de texto. Estas tarefas so feitas normalmente com pouco c a cdigo e usam exaustivamente expresses regulares. o o Suponha que existe, na directoria de trabalho, um cheiro texto.txt que se pretende ler e processar. O seguinte cdigo abre o cheiro para leitura e coloca-o o integralmente no array @texto. Cada elemento deste array ir conter uma linha do a cheiro
open(FILEIN,"<texto.txt"); @texto = <FILEIN>; # O sinal < indica leitura do ficheiro # Carrega o ficheiro no array @texto

Et voil, est feito. O literal FILEIN equivalente a um apontador para cheiro em a a e C, sendo denominado lehandle, ou simplesmente handle em Perl. E igualmente simples escrever um array para dentro de um cheiro. Isso ser a discutido mais adiante. 10

O seguinte bloco de cdigo e o respectivo output exemplicam alguns dos aspectos que o discutimos. Pretende-se apenas dar um cheirinho das facilidades do Perl.
#!/usr/bin/perl # use a linha anterior para auto-executar o script em ambientes Unix/Linux # Escalares $vintpos $vintneg $vflsimple $vflscient $vstr $sref = = = = = = 333; -10; 12.3456; -9.872e+10; "string_1"; \$vintpos ; # # # # # # inteiro positivo... e negativo real em vrgula flutuante... e em notaao cientfica c~ string refer^ncia para $vintpos e

# A numeraao dos prints para facilitar a leitura c~ e print "(1) $vstr interpolada\n"; print (2) $vstr nao interpolada\n; print "\n"; print; $_ = (3) Eu existo e sou $_; print; print "\n"; @varr = (abc, "jk#mk", -12 , "jhj"); print (4) . $varr[1] . "\n"; # interpolaao c~ # sem interpolaao c~ # n~o imprime nada pois $_="" ... a # ...mas agora $_ contm texto! e # muda de linha # inicializa o array @varr # escreve o segundo elemento de @varr

%hash = ( meu, carro, teu, piano , dele , 200, 1000, uff); # inicializa um hash em 2 linhas %hash = ( meu => carro, teu => piano, dele => 200, 1000 => uff); # => equivalente a , em listas e # Esre cdigo equivalente a o e # $hash{meu}=carro; # $hash{teu}=piano; # $hash{dele}=200; # $hash{1000}=uff; print (5) . $hash{teu} . "\n"; $" = " ][ "; print "(6) @varr\n"; @varr = %hash; print "(7) @varr\n"; @varr = keys %hash; print "(8) @varr\n"; @varr = values %hash; print "(9) @varr\n"; # imprime o elemento da chave teu # concatenaao com . c~ # $" separa elementos na escrita de @arrays interpolados # ... a varivel $" por defeito era um espao a c # @varr apanha todo o hash

# @varr apanha as chaves do hash

# @varr apanha os valores no hash

print (10) , quadrado(5);

# imprime resultado de funao c~ # ainda n~o declarada a

11

print "\n(11) ", $sref, " lixo\n"; # imprime refer^ncia em cdigo interno... e o print "(12) ", $$sref, imprimiu $vintpos; # de-refere, i.e., escreve $vintpos print "(13) ", $vintneg + $vflsimple + $vflscient - $hash{dele}, "\n"; # Clculo numrico a e print (14), $hash{meu} . $hash{1000} ; # Concatenaao de strings com . c~ # subprograma ps-declarado o # sub quadrado { my($x) = @_; # nas subrotinas o array especial @_ ... # ... serve para passar os argumentos return $x**2; # return devolve o valor $x**2; # equivalente: sem um return a subrotina devolve o ... # ... ltimo valor calculado no seu corpo. u }

O resultado da execuao deste cdigo com c o


dos> perl code.pl

(supondo que o script com o cdigo denominado code.pl) resulta em o e


(1) string_1 interpolada (2) $vstr nao interpolada\n (3) Eu existo e sou $_ (4) jk#mk (5) piano (6) abc ][ jk#mk ][ -12 ][ jhj (7) dele ][ 200 ][ meu ][ carro ][ 1000 ][ uff ][ teu ][ piano (8) dele ][ meu ][ 1000 ][ teu (9) 200 ][ carro ][ uff ][ piano (10) 25 (11) SCALAR(0x1aa530c) lixo (12) 333 imprimiu $vintpos (13) -98720000197.6544 (14) carro uff

Compare estes resultados com o cdigo (a numeraao nestas linhas est de acordo com as o c a instruoes print do cdigo) e tente correlacion-los. c o a

2.3

Manpages do Perl

Eis (em duas tabelas) uma lista com as manpages exixtentes na distribuiao ocial do c Perl e uma breve descriao de cada uma. Apenas as mais importantes so referidas (faa c a c perldoc perl para ver a lista completa). Sugere-se que consulte as manpages no formato html utilizando um browser. Comece pelo cheiro PERLROOT/html/index.html (onde PERLROOT a raiz da instalaao do Perl no seu sistema.) e c Aps esta introduao um pouco ad-hoc, passa-se a descrever o Perl de uma forma o c sistemtica. a

12

perl perldelta perlfaq perltoc perldata perlsyn perlop perlre perlrun perlfunc perlopentut perlvar perlsub perlmod perlmodlib perlreftut perlref perldsc perllol perlboot perltoot perltootc perlobj perlbot

Introduao ao Perl c Alteraoes no Perl relativamente ` anterior verso c a a FAQ (Frequently Asked Questions) sobre o Perl Indice da documentaao do Perl c Estruturas de dados em Perl Sintaxe do Perl Operadores e regras de precedncia em Perl e Expresses regulares em Perl o Execuao do Perl e opoes (command switches) c c Funoes nativas (intr c nsecas) em Perl Tutorial sobre a funao open() em Perl c Variveis pr-denidas em Perl a e Subrotinas (ou procedimentos) em Perl Funcionamento de mdulos em Perl o Como escrever e usar mdulos em Perl o Breve introduao `s referncias em Perl c a e Referncias em Perl, o resto da histria e o Introduao `s estruturas de dados em Perl c a Estruturas de dados em Perl: arrays de arrays Tutorial de Orientaao para Objectos (OO) em Perl c Tutorial de OO em Perl, parte 1 Tutorial de OO em Perl, parte 2 Objectos em Perl Truques e exemplos de OO em Perl

Tabela 1: Pginas do manual do Perl. a

perlipc perllexwarn perldebug perldiag perlnumber perlsec perltrap perlport perlstyle perlpod perldebguts perldos perlwin32

Comunicaao entre processos em Perl c Avisos em Perl e seu controle Debugging em Perl Mensagens de diagnstico em Perl o Semntica dos nmeros em Perl a u Segurana no Perl c Armadilhas do Perl para tansos... Guia de portabilidade do Perl Guia de estilo da programaao em Perl c Documentaao embebida em cdigo Perl (POD) c o Detalhes acerca do debugging de cdigo o Notas sobre o Perl em DOS Notas sobre o Perl em Windows

Tabela 2: Pginas do manual do Perl (cont.). a

13

Variveis a

Os tipos de variveis dispon a veis, so um aspecto fundamental em qualquer linguagem de a programaao. O Perl suporta um conjunto de tipos de variveis, de operadores e de c a funoes bastante rico. Fazendo a composiao dos tipos bsicos (escalares, arrays e hashes) c c a atravs do uso de referncias, consegue-se implementar virtualmente qualquer estrutura e e de dados. Alm disso, o Perl inteligente (e liberal!) na interpretaao das variveis: por e e c a exemplo, considera como nmeros strings que possam representar de facto um nmero u u (e.g. -3.25e-04). Contrariamente `s linguagens fortemente restritivas na sintaxe a (como o Pascal, o Java e, em menor grau, o C), onde necessrio fazer casts entre tipos e a de variveis diferentes, quase sempre o Perl (que no tem casts) consegue acertar no a a tipo de varivel subentendido pelo utilizador e adequado ` tarefa que se pretende realizar. a a As variveis em Perl so criadas automaticamente na primeira utilizaao. Por exemplo a a c $x = 10.0; cria a varivel escalar $x, $y[23] = "zzz"; cria a varivel do tipo array @y a a com 24 elementos (de 0 a 23). Da mesma forma $z{primeiro} = 1.000; cria o hash %z com uma unica chave primeiro e um unico unico elemento 1,000. A gesto de a memria feita automaticamente. o e Podem ser inicializadas vrias variveis simultaneamente com o mesmo valor a a
$a= $b= $c=0; @aa = @bb = (1,2,hj);

Para eliminar um elemento de um array ou de um hash utiliza-se a funao delete (e.g., c delete $y[23];). Para descobrir se uma dada varivel existe, usa-se o operador defined a (e.g., defined($x)).

3.1

Escalares

Um escalar em Perl tem um nome obrigatoriamente comeado por $. Examine os c seguintes exemplos comentados de escalares e de operaoes com escalares (so utilizados c a arrays e hashes nos exemplos, pois estes contm elementos escalares): e
# script denominado z.pl $integ = 100; $float = 1.33; $str1 = "xpto"; $str2 = "3e3"; @vector = (1,2,3); %hmine = (1,2,"a","ss"); $sref = \$integ; $aref = \@vector; $href = \%hmine; $anonrefa = [a,b,c]; $anonrefb = {a,1,b,10}; print $$anonrefa[1], "\n"; print ${$anonrefb}{b}, "\n"; print $integ + $float, "\n"; print $integ . $float, "\n"; # # # # # # # # # # # # # # # # inteiro float string string numrica, vale 3000 e array hash refer^ncia para $integ e refer^ncia para @vector e refer^ncia para %hmine e refer^ncia annima para array e o refer^ncia annima para hash e o de-referem-se as refer^ncias e ... e imprime-se b e 10 imprime a soma 101.33 imprime a concatenaao 1001.33 c~ ... considerando os nmeros como u

14

print $integ + $str1, "\n"; print $integ + $str2, "\n"; $reftoref = \$sref; print $$$reftoref,"\n"; delete $hmine{1}; delete $$anonrefa[1];

# # # # # # # #

... strings imprime 100 + 0 pois $str1 n~o a ... reconhecida como nmero e u imprime 3100 pois $str2="3e3" ... reconhecida como nmero e u refer^ncia para refer^ncia e e dupla de-refer^ncia igual a $integ e elimina valores de hash e array

O resultado da execuao deste cdigo c o e


b 10 101.33 1001.33 100 3100

Nestes exemplos mostra-se que uma varivel escalar pode conter valores numricos, a e strings e referncias. Alm disso, pode ser conrmado que o Perl liberal: se se utilizar e e e uma string onde deveria estar um nmero, o interpretador verica se a string representa u um nmero (o que acontece com $str2=3000="3e3") e, no caso armativo, considera-a u como um nmero com esse valor. Se a string no tem uma representaao numrica vlida, u a c e a -lhe atribu o valor zero 0 e efectuado, na mesma, o clculo! e do a Se quiser ser avisado destas liberdades do Perl (uma string considerada como 0) invoque-o como perl -w z.pl: o interpretador, quando chega ` linha a
print $integ + $str1, "\n";

produz o seguinte aviso:


Argument "xpto" isnt numeric in addition (+) at z.pl line 18.

Um array @vector e um hash %hmine so preenchidos colocando uma lista de elementos, a separados por v rgulas ou por =>, entre parntesis (...,...=>,...). e Como o hash contm pares chave-valor, o nmero de elementos no preenchimento de e u %hmine dever ser par: mas se fr a o mpar, o Perl no se lamenta e iguala o contedo da a u ultima chave a "" (string nula). Se fr invocado com o interruptor -w d o seguinte aviso: o a
Odd number of elements in hash assignment at z.pl line 7.

3.1.1

Notas sobre referncias e

No anterior bloco de cdigo, $sref, $aref e $href so trs referncias (ou apontadores), o a e e respectivamente para uma varivel escalar, um array e um hash. So constru a a das pondo \ em frente das variveis que para onde vo apontar. a a Por sua vez, $anonrefa e $anonrefb so duas referncias annimas para um array e para a e o um hash. Neste caso, as referncias so criadas igualando-as a uma lista de valores entre e a parntesis rectos [...] ou a uma lista entre chavetas {...}, consoante o se pretenda e referir um array ou um hash. 15

A de-referncia faz-se antecedendo o apontador com o caracter especial que identica o e tipo da varivel apontada. Assim, atendendo ao anterior bloco de cdigo, verica-se que: a o
$$sref equivale a ${$sref} igual a $integ e

e que:
$$anonref{b} equivale a ${$anonref}{b} e equivale a $hmine{b}

A utilizaao ou no de chavetas para de-referir ca ao gosto do programador, embora a c a sua utilizaao clarique o cdigo. Quando se utilizam chavetas, diz-se que se utilizou um c o BLOCO como o nome da varivel (note que um bloco em Perl designa o cdigo entre {...}. a o Podem ser feitas de-referncias sucessivas. Se zermos e
$reftoref = \$sref;

ento a
$$$reftoref equivale a $integ;

e tem o valor 100. Existe outra forma de de-referir arrays ou hashes: o operador seta ->. Lembre-se que $aref e $href eram referncias respectivamente para um array e para um hash. Eis uma e repetiao do cdigo: c o
@vector = (1,2,3); %hmine = (1,2,"a","ss"); $aref = \@vector; $href = \%hmine; # # # # array hash refer^ncia para @vector e refer^ncia para %hmine e

Ento, para obter $vector[2] (que vale 3) com a referncia $aref pode utilizar-se a e $$aref[2], ${$aref}[2] ou $aref->[2]. Da mesma forma $$href{"a"}, ${$href}{"a"} e $href->{"a"} devolvem a string "ss" no hash %hmine. O operador -> tambm utilizado em arrays multidimensionais (ou matrizes) e em outras e e estruturas de dados complexas que discutiremos mais adiante. As referncias que acabmos de descrever, criadas com \, so denominadas referncias e a a e fortes (hard). H outro tipo de referncias: as referncias simblicas. a e e o Quando se tenta de-referir um valor que no uma referncia forte, esse valor tratado a e e e como uma referncia simblica com o nome da varivel. Nas verses anteriores ao Perl 5 e o a o este era o unico tipo de referncias. Veja os seguintes exemplos: e
$nome = "x"; $$nome = 1; ${$nome} = 2; ${$nome x 3} = 3; $nome->[0] = 4; @$nome = (); &$nome(); $nome->{"tu"} = "Maria" ; # # # # # # # # atribui a string "x" a $nome $x = 1; $x = 2; $xxx = 3; cria array @x e atribui 4 a $x[0] limpa @x invoca &x() cria hash %x e atribui "Maria" a $x{"tu"}

As referncias simblicas so extremamente poderosas, mas podem originar bugs dif e o a ceis de detectar. Pode impedir-se o seu uso com o pragma use strict refs; (s permite o o uso de referncias fortes) e voltar a permitir referncias simblicas (por exemplo dentro de e e o um bloco) com o pragma no strict refs;. Rera-se que variveis locais declaradas com my (veja, mais adiante, a discusso de a a subprogramas e variveis locais) no so vis a a a veis na tabela de s mbolos: assim, no podem a ser acedidas por referncias simblicas. e o 16

3.1.2

Strings, listas e expresses regulares. Interpolao o ca

Existem diferentes tipos de string. Apenas apresentmos a sua sintaxe habitual (e.g., a ..., "..."): porm, existem formas alternativas de cri-las que so, por vezes, mais e a a leg veis. O mesmo pode ser dito relativamente a listas e a expresses regulares. o Na tabela 3 so enumeradas as alternativas existentes para criaao/especicaao de a c c strings, de expresses regulares e de listas. o Habitual "" () // s/// y/// Genrica e q// qq// qx// qw// m// s/// tr/// Signicado Literal Literal Comando Lista de palavras Expresso Regular a Substituiao c Transliteraao c Interpolao ca No a Sim Sim No a Sim Sim No a

Tabela 3: Formas equivalentes de especicaao de strings e listas. c Nas formas alternativas, o par ou trio de / pode ser substitu por qualquer par ou trio do a de caracteres no alfanumricos (i.e., no inclu a e a dos em a...zA...Z0...9 e ) e que no sejam espaos (e.g., , \n ou \t). Se forem utilizados parntesis na sintaxe /.../, o c e caracter de abertura ser escolhido de entre ([{ e o caracter de fecho ser o parntesis a a e complementar no grupo )]}. Pode utilizar-se parntesis em s/// ou em tr/// desde que se usem dois pares e compat veis de parntesis, como por exemplo em s{abc}{xyz} ou tr [a-z] /A-Z/. e Repare que neste ultimo exemplo os dois pares de caracteres so diferentes (o que a e permitido) e que se pode incluir espaos entre as trs partes que compem o operador. c e o Para claricar um pouco estas equivalncias, mostram-se alguns exemplos (emparelhados e consecutivamente e partilhando a mesma varivel). a
$xxx $stni $stni $sti $sti # palavra para interpolar # string n~o interpolada a # par^ntesis a abrir ( e a fechar ) e # string interpolada # o caracter | abre e fecha. # qq e | est~o separados por a print $stni, qq/\n/ , $sti , qq[\n]; # qualquer forma admitida em argumentos e $com = cat $0; # $com contm a listagem do actual script... e $com = qx?cat $0? # ... cujo nome est contido em $0 a $com = type $0; # o mesmo em Windows! $com = qx?type $0? @lista = ("a",bb,"ccc","dddd"); # perl -w d aviso sobre o termo bb sem aspas a @lista = qw [a bb ccc dddd]; # n~o preciso usar ou aspas "" nos elementos a e $troca = y#a-z#A-Z#; # maiusculiza a varivel $troca... a $troca = tr [a-z] [A-Z]; # o newline (um espao...) pode ocorrer entre as c # ...partes dos operadores traduao ou substituiao c~ c~ = = = = = malandro; Bom dia!; q(Bom dia!); "O Manuel $xxx\n" ; e qq |O Manuel $xxx\n|; e

17

Pode interpolar-se variveis ou arrays em strings "...", expresses regulares //, etc... a o (veja a tabela 3). Os elementos dos arrays so concatenados entre si com os caracteres a contidos na varivel interna $" que normalmente (e por defeito) um espao . Assim, a e c
$temp=join($",@myarr); print $temp;

equivale a print @myarr;. O Perl disponibiliza operadores para transliterar letras de maiscula para minscula e u u vice-versa: lc STRING devolve a string STRING em minsculas (ou $ se STRING fr omitida). u o lcrst STRING o devolve STRING (ou $ se STRING fr omitida) com o primeiro caracter como minscula. u quotemeta EXPR devolve EXPR (ou $ se EXPR fr omitida) com todos os caracteres no alfanumricos o a e escapados com \. Veja \Q e \E na tabela de caracteres escapados abaixo. uc STRING devolve STRING em maisculas (ou $ se STRING fr omitida). u o ucrst STRING devolve STRING (ou $ se STRING fr omitida) com os primeiros caracteres em o maisculas. u Estas transformaoes podem ser efectuadas em strings interpoladas com caracteres c escapados. Na seguinte tabela, apresentam-se estes caracteres bem como outros caracteres escapados no relacionados com maisculas/minsculas: a u u Escape \cC \\ \" \u \l \U \L \Q \E Signicado control-C backslash ou \ aspa fora o prximo caracter a maiscula c o u fora o prximo caracter a minscula c o u fora todos os caracteres seguintes a maiscula (termina com \E) c u fora todos os caracteres seguintes a minscula (termina com \E) c u escapa os caracteres no alfanumricos seguintes (termina com \E) a e termina \U,\L ou \Q

O Perl possui mais algumas funoes de grande importncia na manipulaao de strings. c a c chr NUMBER Esta funao devolve o caracter ASCII representado pelo nmero. Por exemplo, c u chr(66) d "B". A funao inversa ord(). a c e ord EXPR Esta funao devolve o valor numrico do primeiro caracter ASCII em EXPR. Se EXPR c e fr omitida, usa $ por defeito. Por exemplo, ord("D") 68. A funao inversa o e c e chr(). 18

substr EXPR, OFFSET, LENGTH substr EXPR, OFFSET Esta funao extrai uma sub-string da string dada pela expresso EXPR e devolve-a. c a A sub-string comea no caracter especicado pelo nmero OFFSET, contado a partir c u do in da string (supondo que $[=0). Se OFFSET fr negativo, comea-se a contar cio o c do m da string. LENGTH d o tamanho da string a extrair: se no fr especicado, a a a o extracao feita at ao m da string. Se LENGTH fr negativo, a dimenso da string a c e e o a extrair calculada de forma a terminar |LENGTH| caracteres antes do m da string. e Se substr() aparecer no membro esquerdo de uma atribuiao, EXPR dever ser uma c a varivel vlida. Por exemplo a a substr($nome,0,0) = "Manuel "; junta "Manuel " ao in de $nome. cio index STR, SUBSTR, POSITION index STR, SUBSTR Esta funao devolve a posiao da primeira ocorrncia da sub-string SUBSTR na c c e string STR. Se a posiao POSITION fr especicada, nela que comea a pesquisa. Se c o e c SUBSTR no fr encontrada, a funao devolve a posiao base especicada pelo valor a o c c de $[ (habitualmente 0) menos 1 (assim, habitualmente devolvido -1). e rindex STR, SUBSTR, POSITION index STR, SUBSTR Esta funao funciona como index,s que devolve a posiao da ultima ocorrncia da c o c e sub-string SUBSTR na string STR. Se POSITION fr especicada, a ultima posiao na o e c STR a ser pesquisada. Se SUBSTR no fr encontrada, a funao devolve o valor $[-1. a o c 3.1.3 Operadores aplicveis a escalares a

O Perl tem um leque de operadores extenso e completo. Vejamos alguns operadores aplicveis a escalares. a Operadores algbricos +, -, /, *, **, % onde ** a exponenciaao e % a e e c e diviso modular. Aplicam-se a nmeros. As strings so convertidas para escalares a u a numricos conforme j foi explicado. Vejamos alguns exemplos. e a
$a = 10.0; $b = 5; $c = $a * $b;

# $c vale 50.0

Os operadores de concatenaao . e de repetiao (ou replicaao) x esto c c c a dispon veis para strings. Assim:
$a = 10.0; $b = 5; $c = $a . $b; $d = -; print $d x 80;

# $c vale 10.05 # imprime uma linha com oitenta -

O operador de replicaao tem uma aplicaao interessante em arrays. O cdigo c c o @z = (0) x 11; cria o array @z preenchido com 11 zeros (posioes de 0 a 10). c 19

Os incrementadores ++ e -- comportam-se tal como no C.


$a = 10; ++$a; $a--; $b = $a++; $c = --$a; $s = "cab"; $s++; $a="haa"; ++$a; print $a; # # # # $a $a $a $a vale vale vale e $c 11(equivale a $a++) de novo 10 (equivale a --$a) 11 e $b vale 10 (ps-incremento) o valem 10 (pr-decremento) e O qu^? e

# $s vale "cac"...

Os incrementadores so mgicos! Veja o seguinte cdigo: a a o

Incrementar uma string? Pois , se executar este cdigo, vai ver que no nal e o $a="hab" tendo o Perl tratado a string com caracteres do alfabeto como se fosse um nmero escrito numa base 26! Experimente executar o anterior cdigo com u o $a="ZZZ"... Existem os operadores $var op= $value que equivalem a $var = $var op $value, onde op um dos operadores +=, -=, *=, /=, %=, **=, .=, x=, &=, |=, ^=, <<=, >>=, e &&=, ||=. Funcionam como no C.
$a=20; $b=4; $b += $a $b .= $a $b /= $a

# $b vale 24 # $b vale agora 244 # $b vale 61

Esto dispon a veis os habituais operadores de comparaao <, >, >=, <=, ==, !=, c e <=>. Fazem comparaao numrica. Existem operadores equivalentes (pela mesma c e ordem) para comparaao de strings que so lt, gt, ge, le, eq, ne, e cmp. c a Oops! O C no tem o operador de comparaao <=> (que os perlistas chamam a c carinhosamente de starship operator . . . ). Quando dois escalares so comparados a (por exemplo, $res = $a <=> $b) o resultado $res -1 se $a<$b, 0 se $a==$b e +1 e se $a>$b. O operador cmp tem o mesmo comportamento mas compara strings. Existem os operadores lgicos &&, || e ! (respectivamente e, ou, e no). o a Existem ainda os operadores and, or e not com o mesmo signicado mas com precedncia mais fraca do que os anteriores. e Como em C, o operador condicional ternrio $value = cond ? true value : a false value ; permite atribuir a $value um dos valores true_value ou false_value consoante a condiao cond seja verdadeira ou falsa. Por exemplo c
$x = 10; $z = $x>0 ? "pos": "not-pos";

torna $z igual a "pos" pois $x positivo. e H os operadores aplicveis ao n de bit <<, >>, ~, &, |, e ^ (respectivamente a a vel deslocamento ` esquerda, deslocamento ` direita, complemento, e, ou e ou a a exclusivo). A aplicaao dos operadores de deslocamento exemplicada de seguida: c e
$num = 16 ;

20

$dobro = $num << 1 ; $metade = $num >> 1 ;

# shift de 1 posiao ` esquerda duplica c~ a # shift de uma posiao ` direita divide por 2 c~ a

Os operadores , e => so utilizados de forma equivalente na deniao de listas a c (arrays ou hashes). O operador => particularmente util na escrita de hashes. Veja e mais abaixo. H os operadores de coincidncia =~ e no coincidncia !~ aplicados em expresses a e a e o regulares. A funao length EXPR devolve o nmero de bytes de EXPR em contexto escalar. Se c u EXPR fr omitida, aplica-se implicitamente a $ . Se EXPR fr uma expresso o o a complicada, dever ser escrita entre parntesis, i.e., usa-se length(EXPR). Pode ser a e aplicada a strings para saber a sua dimenso. a Para ver uma listagem completa e a precedncia dos operadores, faa perldoc perlop em e c Windows ou man perlop em Unix/Linux. A t tulo de ajuda, leve em conta que os operadores copiados do C mantm a mesma precedncia. Pode (e deve!) utilizar e e parntesis sempre que tiver dvidas! e u 3.1.4 Funoes matemticas c a

O Perl dispe das funoes matemticas bsicas. Para utilizar funoes especializadas pode o c a a c recorrer-se a mdulos (ou bibliotecas) no CPAN. Eis uma lista das funoes nativas. o c abs VALOR o calcula o valor absoluto do argumento (ou de $ se o argumento VALOR fr omitido). atan2 Y, X calcula o arco-tangente de Y/X no dom nio [, ]. Para obter o valor de faz-se: $pi = atan2(1,1) * 4; cos EXPR calcula o coseno da expresso EXPR (expressa em radianos). Se EXPR fr omitida, a o calcula cos $ . hex EXPR interpreta EXPR como uma string de caracteres hexadecimais e devolve o seu valor numrico (e.g., hex "a0" vale 160). Note que uma string hexadecimal pode comear e c por 0x (isto , hex "0xa0" vale tambm 160). e e int VALOR o devolve a parte inteira do argumento (ou de $ se o argumento VALOR fr omitido). log EXPR esta funao calcula o logaritmo neperiano (de base e) de EXPR, ou de $ caso aquele c argumento seja omitido. oct EXPR interpreta EXPR como uma string de caracteres octais (na base 8) e devolve o seu 21

valor numrico decimal (e.g., oct "055" e oct 055 valem 45). Uma string octal e comea por 0. Se a string comear por "0x" a funao oct() reconhece-a como c c c sendo um nmero em hexadecimal e converte correctamente o seu valor (e.g., oct u "0x55" e oct 0x55 valem 85.) rand EXPR rand calcula um nmero fraccionrio aleatrio que segue uma distribuiao uniforme entre u a o c 0 e EXPR. Se EXPR fr omitida, devolve um valr entre 0 e 1 (1 no est inclu o o a a do). sin EXPR calcula o seno da expresso EXPR (expressa em radianos). Se EXPR fr omitida, a o calcula sin $ . sqrt EXPR sqrt calcula a raiz quadrada de EXPR. Se EXPR fr omitida calcula sqrt $ . Para calcular o ra zes cbicas, etc, pode ser utilizado o operador exponenciaao ** com expoente u c fraccionrio. a srand EXPR srand inicializa o gerador de nmeros aleatrios utilizado pela funao rand. Se EXPR fr u o c o omitida faz srand(time) (que uma operaao cujo resultado bastante previs e c e vel: no a use se pretender cifrar algo importante). a time imprime o nmero de segundos desde 1 de Janeiro de 1970 (actualmente quase 10 9 ). u

3.2

Filehandles (referncias para cheiros) e

Os lehandles (ou handles, para simplicar) so referncias para cheiros externos a e manipuladas nos scripts. So um tipo especial de varivel, que no utiliza nenhum a a a recomendado que o handle seja escrito caracter especial como prexo para o nome. E em mai sculas. Esta regra no obrigatria, mas seguida por quase toda a gente. A u a e o e razo desta recomendaao que qualquer palavra em minsculas potencialmente poder, a c e u a no futuro, vir a ser considerada um comando ou operador em Perl. Cada cheiro manipulado em Perl tem associado um lehandle (ou nome lgico) e um o nome f sico, relacionado com a posiao do cheiro na directoria do sistema. Essa c associaao estabelecida quando o cheiro aberto. Os cheiros podem ser abertos para c e e leitura, para escrita, e para actualizaao (appending). Para ilustrar a utilizaao dos c c handles recorre-se a um pequeno bloco de cdigo. o
# abre o ficheiro aqui.txt na actual directoria # ...para leitura (modo de defeito). $fin interpolado e open(FILEIN,"<$fin") || die("$fin n~o existe!\n") ; a # O mesmo... open(FILEOUT,">d:/text/myout.txt"); # abre ...\myout.txt para escrita open(FILEOUT,">>d:/text/myout.txt"); # abre ...\myout.txt para actualizaao c~ close(FILEIN); close(FILEOUT); # fecha os ficheiros $fin = aqui.txt; open(FILEIN,"$fin");

22

E importante notar alguns aspectos. Primeiro, feita interpolaao de variveis na string e c a com o nome f sico do cheiro se ela fr escrita entre "...". Segundo, a indicaao do modo o c de utilizaao do cheiro dada com < para ler, e este o modo de defeito, com > c e e para escrever)e com >> para acrescentar. Terceiro, o caminho (path) do cheiro e escrito a la Unix, isto , faz uso de / e no de \ como em DOS/Windows. Note que e a isto vlido mesmo para este sistema operativo. Finalmente, embora se tenha fechado e a explicitamente os cheiros com close(FILEHANDLE) no exemplo, no h problema em no a a a o fazer pois, quando termina a execuao do script, todos os cheiros so fechados c a automaticamente. Ainda relativamente ao anterior exemplo, h um outro aspecto importante a reter. A a execuao da funao die("...") (morre...) termina um script e escreve para a consola a c c string dada no argumento. Acontece que na avaliaao de expresses lgicas com vrias c o o a clusulas o Perl comea a partir da esquerda e termina a avaliaao assim que conclui da a c c verdade ou da falsidade da expresso. Ora cond1 || cond2 sempre verdade se cond1 o a e fr. Isto signica que o Perl s executa die("...") se falhar a abertura do cheiro com o o open(FILEIN,"<$fin"), o que indica que ele no existe ou que o utilizador no tem a a privilgio para o abrir, em Unix ou noutro SO que respeite os administradores do sistema e e a privacidade dos utilizadores 8-). Este comportamento do Perl, denominado shortcut evaluation, muito utilizado na e prtica. a E agora, como que se pode ler de e escrever para cheiros? e Para escrever utiliza-se a instruao c
print FILEHANDLE string1, $var, ... , "string2";

que, por defeito, quando FILEHANDLE omitido, escreve para a consola, ou seja, para o e lehandle STDOUT que se encontra automaticamente dispon durante a execuao de vel c programas. Os campos separados por , podem ser variveis escalares ou strings, a interpolveis ou no. A interpolaao de arrays suportada em strings interpolveis (e.g., a a c e a string2 na anterior instruao). c O Perl suporta as instruoes de escrita formatada printf e sprintf. c printf FILEHANDLE FORMATO, LISTA escreve a string FORMATO com as variveis de LISTA a interpoladas de acordo com cdigos semelhantes aos da instruao homnima em C. o c o sprintf FORMATO, LISTA devolve apenas a string. Por exemplo: $nome_de_pessoa = Manel ; $sform = sprintf "Bom dia %s!\n", $nome_de_pessoa ; escreve "Bom dia Manel!. O cdigo %s indica que $nome_de_pessoa uma string. o e Consulte o manual para saber, em detalhe, quais os cdigos de formataao dispon o c veis para as funoes printf e sprintf. c Na leitura de dados de cheiros manifesta-se a versatilidade do Perl. Para ler uma linha do cheiro associado a FILEIN para a varivel escalar $line faz-se a
$line = <FILEIN>;

Para ler a totalidade do cheiro associado a FILEIN para um array @arrayfile faz-se
@arrayfile = <FILEIN>;

Este um exemplo da execuao de uma mesma expresso ` direita (neste caso e c a a <FILEIN>;) em contexto escalar ou em contexto de lista. Consoante o tipo de varivel que a se encontra no membro esquerdo da atribuiao (escalar ou array/lista), assim o modo c e 23

como os dados so lidos de FILEIN. a Mais adiante, quando falarmos da execuao de tarefas repetitivas em Perl (com while, c until, for, foreach, ...) retomaremos o tpico da leitura de dados de cheiros externos. o Por exemplo, ser ilustrada a leitura de cheiros, caracter a caracter, com as funoes a c getc(FH) e eof(FH) que, de uma forma semelhante ao C, respectivamente lem um e caracter do cheiro associado ao lehandle FH ou detectam o seu m (end-of-le). 3.2.1 Operadores de teste a cheiros

O Perl dispe de operadores de teste aplicveis a cheiros. Permitem avaliar o tipo do o a cheiro, as permisses de acesso, etc. So operadores unrios. Eis alguns exemplos: o a a
$dim = -s "c.pl"; # $dim guarda o tamanho do ficheiro c.pl na actual directoria print "Ficheiro de texto\n" if -T "texto.txt"; # verifica se ficheiro de texto e print "Ficheiro n~o existe\n" if !(-e "file.dat"); a # verifica se file.dat n~o existe a

A tabela seguinte enumera alguns destes operadores que testam, quer o cheiro, quer as permisses do utilizador (so agrupados mais do que um em cada linha). o a Operadores -r, -w, -x; -o -R, -W, -X; -O -e, -z; -s -T, -B -M, -A -f, -d, -l -b, -c Signicado permisso de ler, escrever, executar; posse a permisso de ler, escrever, executar; posse a existe, tem dimenso zero; devolve a dimenso a a cheiro de texto, cheiro binrio a tempo desde o/a ultimo/a modicaao, ou acesso c cheiro, directoria, link simblico e e e o cheiro especial de blocos, ou de caracteres

Estes operadores aplicam-se quer a nomes f sicos de cheiros quer a lehandles. 3.2.2 Tpicos mais avanados na utilizao de <...> o c ca

Viu-se a utilizaao do operador <FHAND> contendo um lehandle FHAND genrico, c e normalmente escrito em maisculas. Porm, esta no a unica forma de utilizar o u e a e interior de <...>. Se a string encerrada por este operador fr uma varivel escalar (por exemplo <$foo>) e o a contiver o nome do lehandle que se pretende aceder ou uma referncia para ele, o Perl e entende e acede ao cheiro associado. Veja o exemplo.
open(MYSELF,$0); $fh = MYSELF; $fh = \*MYSELF; $line = <$fh>; # # # # abre o prprio script. $0 contm o nome do script o e guarda o nome do filehandle... ...ou a refer^ncia para o filehandle ( equivalente) e e l^ a primeira linha do script e

Se entre <...> estiver uma expresso que no seja um handle ou uma varivel (mesmo a a a que sejam s espaos! Por exemplo, no anterior cdigo $line = < $fh>; j no era o c o a a interpretado correctamente por causa do espao extra), o Perl interpreta o interior de c <...> como um padro de nomes de cheiros na actual directoria. Por exemplo, a executando @perlfiles = <*.pl>; coloca-se no array @perlfiles o nome de todos os scripts com suxo .pl existentes na actual directoria. 24

3.2.3

Outras funoes de acesso a cheiros c

O Perl possui mais algumas funoes de leitura/escrita/processamento de cheiros. c seek FILEHANDLE, OFFSET, OFFSETMODE coloca o ponto de acesso ao cheiro referido por FILEHANDLE na posiao especicada por OFFSET (a posiao inicial no cheiro zero). O c c e modo OFFSETMODE igual a 0/1/2 indica, respectivamente, se OFFSET contado a partir do e in cio, da actual posiao, ou do m do cheiro. A unidade de contagem so bytes. c a tell FILEHANDLE devolve a actual posiao de leitura no FILEHANDLE em bytes, a contar c de 0. Se FILEHANDLE fr omitido aplica-se ao ultimo cheiro que foi lido. o read FILEHANDLE, ESCALAR, TAMANHO, OFFSET tenta ler TAMANHO bytes de dados do cheiro associado a FILEHANDLE e armazen-los na varivel ESCALAR. A funao devolve o a a c nmero de bytes efectivamente lidos ou 0, caso encontre o m do cheiro. Devolve undef u se ocorrer um erro. O valor de OFFSET (se utilizado) especica a posiao na string c ESCALAR onde se comea a escrever os dados. c write FILEHANDLE escreve um registo formatado de acordo com a deniao de formats. c Veja o manual perlform.

3.3

Dirhandles (referncias para directorias) e

O Perl possui um conjunto de funoes para lidar com directorias que se descreve c sucintamente. rmdir DIRNAME apaga a directoria especicada por DIRNAME se ela estiver vazia. Se rmdir fr bem sucedida, devolve 1; se no, devolve 0 e escreve um cdigo de erro em $!. Se o a o DIRNAME fr omitido, rmdir opera sobre o contedo de $_. o u chdir EXPR muda a actual directoria de trabalho para EXPR, se poss vel. Se EXPR fr o omitida, muda para a home do utilizador. chdir devolve 1 em caso de sucesso. Em caso de insucesso devolve 0 e escreve um cdigo de erro em $!. o mkdir DIRNAME, MODO cria a directoria especicada por DIRNAME com o modo especicado por MODO. Devolve 1/0 em caso de sucesso/insucesso. No insucesso, escreve o cdigo de o erro em $!. opendir DIRHANDLE, EXPR abre a directoria de nome EXPR e associa-a ` referncia lgica a e o DIRHANDLE, para posterior processamento por readdir, telldir, seekdir, rewinddir e closedir. A funao devolve verdade, em contexto lgico, se foi bem sucedida. As c o dirhandles tm uma tabela de nomes independente da tabela de nomes dos lehandles. e closedir DIRHANDLE fecha a directoria aberta com opendir. telldir e seekdir estabelecem o posicionamento de leitura da directoria por parte de readdir. rewinddir coloca a actual posiao de leitura da funao readdir no in c c cio, i.e., em DIRHANDLE. A funao mais importante readdir DIRHANDLE. Por exemplo, para processar a actual c e directoria de trabalho pode fazer-se:
opendir TRABALHO, "." or die "A directoria . n~o existe ???: $!"; a @todos = readdir TRABALHO; # l^ a directoria para um array e @textos = grep -T, readdir TRABALHO; # l^ s ficheiros de texto e o

25

closedir TRABALHO; print "@todos\n";

# fecha a dirhandle # lista-a (equivale a dir ou ls)

3.4

Arrays (ou vectores ou listas)

Os arrays so variveis cujo nome comea por @ e consistem de uma lista de elementos a a c indexados por um nmero inteiro. Podem ser criados explicitamente com uma lista de u elementos separados por v rgulas como, por exemplo, @vector = (1,2,3); A primeira posiao de um array 0: este c e ndice pode ser mudado com a varivel especial a $[ (e.g., $[=1;) mas isto no recomendado. No necessrio declarar arrays, a no ser a e a e a a que seja usado o pragma use strict; que fora a declaraao de todas as variveis. Pode c c a eliminar-se elementos de arrays ou de hashes com a funao delete (e.g delete c $myarray[3]; ou delete $myhash{boo};). O delete de um elemento de um array no lhe altera a dimenso, pois o elemento apagado ca undened mas a clula no a a e a desaparece. Se quiser eliminar uma clula de um array use splice. e Ao igualar um escalar a um array, atribui-se-lhe o nmero de elementos (ou dimenso) do u a array. Por exemplo
$tamanho = @vector;

faz com que $tamanho = 3 (pois @vector tem 3 elementos). Cada array tem associada uma varivel escalar especial que contm o maior a e ndice existente no array. Para um array denominado @arrxpto essa varivel $#arrxpto (substitui-se @ por $# na denominaao a e c do array). Assim, $#arrxpto vale dois no exemplo (o array @arrxpto tem elementos nas posioes 0, 1 e 2). c a E fcil copiar arrays. Suponha que temos um array @bb = ("00", 1 , "22", 333, 4); e que se faz a seguinte atribuiao c @aa = @bb; A atribuiao entre dois arrays @aa = @bb; iguala o array @aa a @bb. Nesta igualdade, a c duplicao feita por valor e no por referncia (contrariamente, por exemplo, ao ca e a e python, onde quando dois arrays so igualados a operaao feita por referncia, a no ser a c e e a que se force uma duplicaao). Isso pode ser vericado com o seguinte cdigo c o
@arr = (0,1,2,3,4); @barr = @arr; $arr[2] = foo; print "@barr\n"; print "@arr \n";

# imprime 0 1 2 3 4 # imprime 0 1 foo 3 4

Como se v, a alteraao em $arr[2] no alterou o valor de $barr[2] que tinha sido e c a previamente copiado. Um array uma lista. A atribuiao @aa = @bb apenas a atribuiao impl e c e c cita de uma lista a outra. A cpia pode ser realizada entre listas de escalares. Por exemplo o ($a,$b,$c) = ($x,$y,$z); realiza trs atribuioes de escalares simultaneamente. Este mecanismo muito util para e c e trocar os valores de dois escalares (o denominado swap) fazendo-se
($a,$b) = ($b,$a); # Troca os valores de $a e $b duma penada!

Podem retirar-se fatias (slices ) de arrays com o operador .. denominado operador 26

gama (de range em Ingls, no da letra grega...) Veja o exemplo: e a


@arr=(0,1,2,3,4,5,6); @fatia = @arr[1..3]; # @fatia = (1,2,3); push @arr, @fatia; # copia @fatia para o fim de @arr # equivalente a push @arr, (1,2,3);

No nal, @arr=(0,1,2,3,4,5,6,1,2,3), isto , tem 10 elementos. A funao push e c concatena duas listas (ou arrays), pondo o resultado na primeira lista. A concatenaao de vrios arrays tambm simples. Executando c a e e
@tar = (@aar, @bar, @car);

o array @tar ca com a concatenaao dos trs vectores nesta lista. c e O Perl tem vrias funoes de manipulaao de arrays e listas, algumas das quais j a c c a referimos. Vejamos as mais uteis: note que algumas so aplicveis a strings (listas de a a caracteres). chomp VARIABLE chomp LIST chomp Veja a descriao de chop a seguir. chomp semelhante a chop, sendo a unica c e diferena o facto de remover o ultimo caracter apenas se fr igual a varivel c o ` a pr-denida $/ (separador de registos no Perl ) que por defeito \n. e e chop VARIABLE chop LIST chop Esta funao remove e devolve o ultimo caracter da linha. Serve frequentemente para c remover \n do m das linhas. Se o argumento VARIABLE no fr especicado, a o aplica-se implicitamente a $ . Quando aplicada a uma lista LIST, remove o ultimo caracter de todas as strings na lista e devolve o caracter removido ao ultimo elemento da lista. die LIST Termina a execuao do programa e escreve na consola uma string que a c e concatenaao de LIST com a varivel de erro interna $! (tambm conhecida por c a e ERRNO). dened EXPR Esta funao devolve um valor Booleano indicando se EXPR tem valor real ou no. c a Um escalar que no contm uma string, referncia ou nmero vlidos, um valor a e e u a e indenido (undened) ou, simplesmente, undef. Muitos operadores devolvem undef em condioes de excepao (m de cheiro, erro de sistema, etc...). A funao c c c defined permite distinguir entre uma string nula indenida e uma string nula denida. defined tambm permite avaliar da existncia (ou deniao) de arrays, hashes e e e c subrotinas. Quando usado num elemento de um hash, defined apenas diz se o valor guardado nessa chave est ou no denido, nada diz sobre a chave em si. Para determinar se a a existe uma dada chave num hash usa-se a funao exists. c

27

pop ARRAY pop Esta funao usa um array como pilha (stack): remove e devolve o ultimo elemento c do ARRAY, encurtando-o. Se ARRAY fr omitido, aplica-se a @ARGV (no programa o principal) e a @ dentro de subrotinas. O comportamento de pop : e
$tmp = pop @ARRAY; # pop ... $tmp = $ARRAY[$#ARRAY--]; # equival^ncia ... e $tmp = splice @ARRAY, -1; # outra equival^ncia e

Se o array est vazio, pop devolve undef. Veja tambm push, shift, unshift e a e splice (splice permite remover um maior nmero de elementos do array). u push ARRAY, LISTA push usa tambm um array como stack: puxa os valores na LISTA para o m do e ARRAY e aumenta a dimenso deste de acordo com a dimenso da LISTA. A funao a a c devolve um escalar com a nova dimenso do ARRAY. Eis alternativas a push (note, a porm, que push mais eciente): e e
push @ARRAY, @LISTA; # equivalente a foreach $value (LISTA) { $ARRAY[++$#ARRAY] = $value; } # equivalente ainda a splice @ARRAY, @ARRAY, 0, @LISTA;

reverse LISTA (Veja sort). Devolve uma lista com os elementos de LISTA por ordem inversa. E uma operaao eciente. Em contexto escalar, a funao concatena todos os elementos c c da lista numa string e devolve-a pela ordem inversa, caracter a caracter. shift ARRAY shift Remove o primeiro valor do array e encurta-o de 1 elemento. Se ARRAY est vazio, a shift retorna undef. Se ARRAY fr omitido, shift aplica-se a @ARGV no programa o principal e a @ nas subrotinas. Veja tambm push, pop, unshift e splice. shift e e unshift fazem, no in do ARRAY, o mesmo que pop e push fazem no m. cio sort {code} LISTA com {code} omitido, ordena a LISTA por ordem crescente, segundo o critrio de e comparaao alfabtico, e devolve-a. {code} pode ser cdigo annimo ou o nome de c e o o uma subrotina. Veja o manual perlfunc para saber detalhes da escrita de code. O seguinte exemplo compara dois critrios de ordenaao: e c
@w = (1,11,011); @z = sort @w; print "@z\n"; @z = sort {$a <=> $b} @w; print "@z\n"; # # # # # nmeros 1, 11 e 9 (em octal) u ordenaao (crescente) com critrio alfabtico c~ e e imprime 1 11 9 ordenaao (crescente) com critrio numrico c~ e e imprime 1 9 11

splice ARRAY, OFFSET, LENGTH, LISTA splice ARRAY, OFFSET, LENGTH 28

splice ARRAY, OFFSET Esta funao remove os elementos do ARRAY especicados pela posiao inicial OFFSET c c e pela dimenso LENGTH, e substitui-os pela lista LISTA, se fr especicada. A a o funao devolve os elementos removidos. O array encurta ou cresce conforme c necessrio. Se LENGTH fr omitido, a remoao feita desde a posiao OFFSET at ao a o c e c e m do array. Se OFFSET fr negativo, comea-se a contar do m do ARRAY. Se o o c in do array @a fr na posiao 0 (o que especicado pela varivel especial $[) as cio o c e a seguintes equivalncias so vlidas: e a a
push(@a, $x, $y); pop(@a); shift(@a); unshift(@a, $x, $y); $a[$x] = $y; # # # # # equivalente equivalente equivalente equivalente equivalente a a a a a splice(@a, splice(@a, splice(@a, splice(@a, splice(@a, $#a+1, 0, $x, $y); -1); 0, 1); 0, 0, $x, $y); $x, 1, $y);

unshift ARRAY, LISTA unshift faz no in do ARRAY o mesmo que push faz no seu m: insere LISTA no cio in do ARRAY e devolve a sua nova dimenso (aumentada). cio a warn LISTA Esta funao escreve a mensagem contida em LISTA no handle STDERR,` semelhana c a c de die, mas no termina o script nem acciona uma excepao. a c 3.4.1 Converso entre arrays e strings a

Um array uma lista. Uma string pode ser uma lista de palavras (ou termos). O Perl e tem funoes para converter arrays em listas e vice-versa. Essas funoes so: c c a join EXPR, LISTA Concatena os elementos de LISTA numa unica string, inserindo entre eles o(s) caracter(es) devolvido(s) pela expresso EXPR. Devolve a string assim constru a da. Por exemplo:
@a = qw(a d f gh jk l); @b = qw/1 2 3 4 5/; $dd = join :, @a, @b; print $dd,"\n";

# a lista pode ser uma concatenaao de listas c~ # imprime a:d:f:gh:jk:l:1:2:3:4:5

Contrariamente a split, join no usa uma expresso regular no argumento EXPR. a a A forma mais eciente de concatenar muitas strings utilizar join com a string e nula no lugar de EXPR ( mais eciente que o operador de concatenaao .). e c split /PATTERN/, EXPR, LIMITE split /PATTERN/, EXPR split /PATTERN/ split Esta funao examina a string dada por EXPR para a existncia dos delimitadores c e especicados por /PATTERN/, separa-a numa lista de substrings, e devolve essa lista 29

em contexto de lista ou o nmero de substrings em contexto escalar. O delimitador u PATTERN pode ser uma expresso regular. Se o delimitador no fr encontrado na a a o string original, split devolve-a. Se LIMITE fr especicado, o nmero de substrings o u no excede este valor. Se EXPR fr omitida, split aplicado implicitamente a $ . Se a o e /PATTERN/ fr omitido, a separaao feita por espaos (i.e., o separador a o c e c e expresso regular /\s+/). Exemplos: a
@caracteres = split //, $palavra; @campos = split /:/, $linha ; @palavras = split , $paragrafo ; ($nome,$idade) = split / /, $registo, # # # 2 separa $palavra caracter a caracter separa $linha pelos dois pontos : separa $paragrafo por um espao c ; # l^ primeiros 2 campos do $registo e

No processamento de cheiros de texto, comum considerar cada linha como um registo. e O Perl tem a varivel $/ que dene o separador de registos e que vale \n por defeito. a

3.5

Contexto escalar e contexto de lista

Um dos aspectos mais singulares do Perl a distinao entre os contextos de lista e de e c escalar. O seguinte bloco de cdigo ilustra a diferena: o c
@v = (1,2,3,4,5); @u = @v; # o array @u uma cpia de @v e o $a = @v; # $a fica igual a 5 (i.e., ` dimens~o do array @v) a a

Observa-se pois, que um mesmo literal, @v, interpretado de duas formas diferentes e consoante o contexto em que interpretado: num contexto escalar representa a e dimenso do array; num contexto de lista representa o prprio array. a o Note-se que no apenas um literal array (comeado por @) que pode ser avaliado de a e c forma diferente nos dois contextos. A funao key %hash devolve um array com todas as c chaves do %hash. Veja, ento, este exemplo a
%hash = (a,1,b,2,c,3,d,4,e,5,f); @arr = keys %hash; # contexto de lista $numkeys = keys %hash; # contexto escalar print "@arr", "\n"; print "$numkeys", "\n"; # 6 chaves, 5 elementos

imprime
e f a b c d 6

As chaves de %hash no so extra a a das ordenadamente; se se pretendesse orden-las a quando so guardadas em @arr deveria fazer-se a
@arr = sort keys %hash;

A funao sort ordena a lista alfabeticamente (por ordem crescente). Se se pretender uma c ordenaao por ordem decrescente utiliza-se reverse c
@arr = reverse sort keys %hash;

Se se quiser forar uma lista a um contexto escalar pode usar-se c


scalar(@list);

ou efectuar a adiao escalar @list + 0;. c

30

3.6

Programao funcional: grep e map ca

As funoes grep e map permitem efectuar transformaoes em todos os elementos de uma c c lista. Este tipo de funoes est associado a um paradigma de programaao denominado c a c programaao funcional. c grep BLOCO LISTA grep EXPR, LISTA grep executa o bloco de cdigo BLOCO, ou a expresso EXPR, para cada elemento da o a LISTA (igualando, a n local, $ a cada elemento). Em contexto de lista, devolve a vel lista de elementos para os quais BLOCO ou EXPR so verdadeiros. Em ambito escalar, a grep devolve o nmero de execuoes verdadeiras. Por exemplo, para remover u c linhas de comentrio num cheiro Perl (guardado no vector @bar), pode fazer-se a @foo = grep(!/^\s*#/, @bar); ou, equivalentemente, @foo = grep {!/^\s*#/} @bar; $ pode ser usada para modicar os elementos do array (funciona como uma referncia para cada elemento da lista). Esta modicaao pode causar resultados e c bizarros se a lista no fr um array nominal (e.g., se fr uma lista annima). a o o o map BLOCO LISTA map EXPR, LISTA map executa o bloco de cdigo BLOCO ou a expresso EXPR para cada elemento da o a lista LISTA (igualando a n local $ a cada elemento) e devolve a lista com os vel resultados da execuao. Em contexto escalar, map devolve o nmero de elementos c u gerados. BLOCO ou EXPR so executados em contexto de lista, e assim cada elemento da a LISTA pode gerar zero, um, ou mais elementos na lista devolvida. Por exemplo
@chars = map(chr, @nums);

traduz uma lista @num contendo nmeros para os respectivos caracteres ASCII e u %hash = map { getkey($_) => $_ } @array; uma maneira curtida de fazer e
%hash = (); foreach $_ (@array) { $hash{getkey($_)} = $_; }

Mais uma vez se chama a atenao para a modicaao da LISTA atravs da referncia c c e e impl cita $ : pode causar resultados estranhos se a LISTA no fr nominal. a o A programaao funcional permite compactar ecazmente operaoes em listas de c c elementos. Por exemplo, considere a lista de nmeros @n = (1,2,3,5,6,7,9) cujos cubos u quer imprimir. Isto feito compactamente com e print map($_**3 , @n); que imprime 1827125216343729, o que no possivelmente o que pretende, pois os a e nmeros so escritos sem separador. Para os imprimir separados por um espao, u a c modica-se a anterior instruao por forma a juntar um espao a cada cubo: c c 31

print map($_**3 . , @n), "\n"; que escreve 1 8 27 125 216 343 729 na consola.

3.7

Hashes (dicionrios) a

Os hashes, ou dicionrios, so listas de elementos indexadas por uma chave do tipo a a string, contrariamente aos arrays que so indexados por um inteiro positivo. Os hashes a so inicializados da seguinte forma: a
@hax = (a, 10, bb, "hello", 20, Ist); @hax = (a => 10, bb => "hello", 20 => Ist); # equivalente

Esta ultima forma mais leg e vel. A seta => equivalente ` v e a rgula na deniao de c listas (tambm podia ser utilizada a forma alternativa de criaao de listas qw/.../). e c O Perl tem funoes dedicadas ` manipulaao e processamento de hashes. c a c dbmclose %HASH Quebra a ligaao estabelecida entre uma base de dados (tipo DBM) e o %HASH. Veja c dbmopen. dbmopen %HASH, dbname, mode Estabelece ligaao entre uma base de dados (BD) dbname (em formato DBM) e o c %HASH. O modo mode aquele utilizado em Unix para especicar as permisses e o associadas a cheiros (e.g. 0777 permite a leitura e a escrita do cheiro a todos os utilizadores). A execuao de dbmopen cria os cheiros dbname.pag e dbname.dir, c caso a BD ainda no tenha sido criada. dbname pode incluir um path (e.g, a c:/bdados/dbname). Apenas os valores inseridos em %HASH depois da execuao de c dbmopen, ou j existentes na BD, esto acess a a veis. Eis um exemplo de inicializaao c de uma BD (so criados na directoria de trabalho os cheiros xpto.pag e xpto.dir): a
dbmopen %xpto, xpto, 0777; $xpto{a} = 100 ; dbmclose %xpto;

dbmopen e dbmclose podem ser utilizadas para realizar BDs de mdia complexidade. e delete $HASH{HASHKEY} Apaga a chave $HASH{HASHKEY} do HASH. O argumento de delete pode ser qualquer expresso arbitrria que devolva a chave de um elemento de HASH. a a each HASH Esta expresso devolve uma lista de 2 elementos com a CHAVE e o respectivo VALOR a no hash HASH. Utilizando sucessivamente each, pode examinar-se completamente um hash. Aps o hash ser completamente lido, each devolve uma lista nula que o e falsa num teste condicional. Por exemplo
while (($key,$value) = each %hash) { print "$key,$value\n"; } # escreve todos os pares chave-valor existentes no %hash

exists $HASH{HASHKEY} Esta funao retorna verdade se a chave HASHKEY existe no hash HASH, mesmo que o c 32

seu valor seja undef. O argumento de exists pode ser qualquer expresso ou a funao que devolva uma chave de hash. c keys HASH Devolve uma lista com todas as chaves do hash HASH, numa ordem aparentemente aleatria. Esta ordem a mesma encontrada na aplicaao das funoes each ou o e c c values ao hash (se este no foi modicado entretanto). a Em contexto escalar, keys d o nmero de elementos do hash (e faz reset ao a u iterador each). keys pode ser utilizada numa atribuiao, permitindo aumentar a c memria utilizada pelo hash (o que melhora o tempo de acesso) o keys %HASH = 200; values HASH Devolve uma lista com todos os valores guardados no hash HASH, pela mesma ordem que seria obtida na aplicaao das funoes each ou keys (se aquele entretanto no foi c c a modicado).

3.8

Variveis especiais a

O Perl implementa um grande nmero de variveis pr-denidas. Algumas so utilizadas u a e a implicitamente em diversas funoes. Permitem escrever rapidamente cdigo denso e c o compacto (pois no so vis a a veis no cdigo as variveis envolvidas). Como diz Larry Wall, o a o pai e me do Perl, todo o programador preguioso. a e c Lembre-se que no C existem duas variveis pr-denidas que permitem aceder aos a e argumentos da linha de comando: argc e argv. Pode pensar, se quiser, que o Perl tem uma grande variedade (e quantidade...) destas variveis especiais. a A maioria destas variveis tem um nick-name constitu pelo caracter associado ao seu a do tipo ($ para um escalar, @ para um array e % para um hash) e por outro (ou outros) caracter no alfanumrico. Exemplos: $ , @ , @ARGV, %ENV, $[, .... a e Para alm do nick-name as variveis pr-denidas tm uma denominaao respeitvel e a e e c a utilizada pelos programadores com classe 8-). Para invocar estes nomes respeitveis a escreve-se o pragma use English; no in do programa. Algumas variveis tm 3 cio a e denominaoes, ao todo, sendo a terceira emprestada pela linguagem de programaao awk. c c Na secao do manual denominada perlvar encontra-se uma lista completa destas variveis c a (faa perldoc perlvar para a consultar). Eis aqui uma selecao das mais importantes c c (as denominaoes compridas esto associadas ` invocaao do pragma use English;): c a a c $ARG, $ E o escalar utilizado por defeito para entrada de dados. Os seguintes pares de instruoes so equivalentes: c a
while (<>) {...} # equivalente s num while! o while (defined($_ = <>)) {...} /^Subject:/ $_ =~ /^Subject:/ tr/a-z/A-Z/; # coincid^ncia (acerto) em express~es regulares e o

# transliteraao c~

33

$_ =~ tr/a-z/A-Z/; chomp; chomp($_); # remoao de \n no fim de $_ c~

a c O Perl assume implicitamente $ como argumento em vrias funoes, quando estas so invocadas sem argumento: a Vrias funoes unrias, incluindo ord() e int(), assim como todos os testes a a c a cheiros (-f, -d, ...) excepto -t, que testa STDIN por defeito. Vrias funoes aplicveis a listas, print() e unlink(). a c a Os operadores de pattern matching como m//, s///, e tr///. $ a varivel de iteraao por defeito em listas sujeitas ao ciclo foreach (ou e a c for) se no fr especicada qualquer varivel de iteraao: a o a c foreach (@lista) { processa... } # $_ itera a @lista for (@lista) { processa... } # equivalente e a c cita nas funoes grep() e map(). c $ a varivel de iteraao impl $ a varivel para onde lido um registo de entrada quando um operador e a e <FH> (leitura de lehandle) testado como unico critrio num while. Fora e e dum teste a um while isto no acontece. a $<digits> (Por exemplo $1, $2 ...) Contm a sub-pattern no correspondente par de parntesis e e curvos (...) aps uma coincidncia bem sucedida com expresses regulares. As o e o variveis $<digits> apenas podem ser lidas, so locais ao bloco onde a coincidncia a a e est a ser feita e so criadas dinamicamente. Veja a secao dedicada `s expresses a a c a o regulares ou o manual perlre. $MATCH, $& A string resultante da ultima pesquisa de texto (pattern match) bem sucedida. Esta varivel apenas pode ser lida, local ao bloco onde a pesquisa est a ser feita e a e a dinmica. (A sua utilizaao penaliza fortemente o tempo de execuao das e a c c operaoes com expresses regulares). c o $PREMATCH, $ $POSTMATCH, $ $LAST PAREN MATCH, $+ @LAST MATCH END, @+ @LAST MATCH START, @$MULTILINE MATCHING, $* (o uso desta varivel desaconselhado) a e Estas variveis tm a ver com o sucesso numa pesquisa de texto com expressses a e o regulares. Consulte o manual perlre para detalhes. $INPUT LINE NUMBER, $NR, $. O nmero correspondente ao corrente registo (record) do ultimo lehandle lido u com read(), seek(), ou tell(). Habitualmente, um registo uma linha e o m do e registo assinalado por \n (para mudar o caracter que assinala o m do registo e altera-se $/). Um close expl cito do cheiro faz $. igual a zero. Como <> no a 34

efectua um close expl cito, $. vai sempre aumentando quando se l uma lista de e cheiros atravs de @ARGV com o operador <>. e $INPUT RECORD SEPARATOR, $RS, $/ O separador de registos de entrada. Por defeito, o m-de-linha \n. Esta varivel e a altera a ideia do Perl sobre o m de linha. Considera as linhas em branco como o separador de registos quando se faz $/="" (i.e., a string nula). Se $/ fr igualada a e o um conjunto de caracteres, ser este conjunto que termina cada registo (e.g., a $/="-:-"). Se fr aplicada a funao undef a $/, a leitura do cheiro com uma o c varivel escalar engole (slurp) todo o cheiro. Veja este exemplo a
undef $/; $_ = <FH>; s/\n[ \t]+/ /g; # entra em modo de engolir # l^ todo o ficheiro e # substitui tabs e newlines por espaos c

Atenao: o valor que se atribui a $/ uma string e no uma regex. c e a Igualando $/ a uma referncia para inteiro, para escalar contendo um inteiro, ou e para escalar convert para inteiro, faz-se com que a leitura seja realizada por vel registos (e no por linhas) com uma dimenso mxima denida por aquele inteiro. a a a Assim
$/ = \32768; # ou \"32768", ou \$var_contendo_32768 open(FILE, $myfile); $_ = <FILE>;

l um registo com no mais do que 32768 bytes do cheiro $myfile. e a $OUTPUT AUTOFLUSH, $| Se diferente de zero, fora o flush (escrita) do buer de sa de dados aps cada c da o write ou print. O valor por defeito 0. e $OUTPUT FIELD SEPARATOR, $OFS, $, O separador dos campos no operador print (neste operador os campos so a separados por , e assim $, dene os caracteres escritos em vez da v rgula). Pode ser alterada pelo programador. $OUTPUT RECORD SEPARATOR, $ORS, $\ O separador de cada registo no operador print, ou seja, o que escrito no canal de e sa (e.g., na consola) no m de cada linha escrita com print.Pode ser alterada da pelo programador: por exemplo, se se zer $\="\n"; muda-se de linha com cada print ($\= por defeito). $LIST SEPARATOR, $ Esta varivel funciona como $, s que se aplica na escrita de arrays (ou fatias de a o arrays) interpolados numa string. Por defeito um espao. e c $SUBSCRIPT SEPARATOR, $SUBSEP, $; O separador de ndices para emulaao de arrays multidimensionais com hashes. Se c se referir um elemento de um hash com $foo{$a,$b,$c} o Perl transcreve isto para $foo{join($;, $a, $b, $c)}. Atenao, no use @foo{$a,$b,$c} que representa c a 35

uma fatia (slice) pois comea por @ e signica ($foo{$a},$foo{$b},$foo{$c}). O c valor por defeito de $; \034. Na prtica, deve utilizar-se arrays e a multidimensionais reaiscomo descrito no manual perllol. e $OFMT, $# O formato de impresso de nmeros. O valor de defeito "%.ng". A modicaao de a u e c $# desaconselhada. e $FORMAT PAGE NUMBER, $% (e ainda $= $- $~ $^ $: $^L $^A). Variveis utilizadas em formatos (uma a facilidade disponibilizada pelo Perl para formatar relatrios. Consulte a pgina o a perlform do manual.) $CHILD ERROR, $? Varivel que armazena o estado da ultima chamada ao sistema operativo. a $OS ERROR, $ERRNO, $! Se utilizado como string, d a string de erro de sistema correspondente. a $EXTENDED OS ERROR, $^E Erro de sistema espec co em alguns sistemas operativos. Na maioria dos sistemas operativos igual a $!. e $EVAL ERROR, $@ A mensagem de erro de sintaxe aps a ultima execuao de um eval(). Se fr a o c o string nula (i.e. igual a "") o ultimo eval() encontrou uma sintaxe correcta e executou o cdigo sem erros. o $PROCESS ID, $PID, $$ O nmero do processo correspondente ` execuao do presente script pelo Perl u a c (considere a varivel s de leitura). a o $REAL USER ID, $UID, $< $EFFECTIVE USER ID, $EUID, $> $REAL GROUP ID, $GID, $( $EFFECTIVE GROUP ID, $EGID, $) Variveis relacionadas com a identicaao do utilizador que executa o Perl e que a c permite controlar os seus privilgios. So importantes para a segurana do sistema. e a c $PROGRAM NAME, $0 O nome do programa (script) que est em execuao. a c $[ Especica qual o ndice do primeiro elemento de um array e do primeiro caracter duma string. Vale 0 por defeito. Pode ser igualada a 1 (por exemplo), mas e desaconselhada a sua alteraao. c $] Contm a verso + patchlevel / 1000do interpretador Perl. Pode ser utilizada e a para determinar se se tem a verso adequada de Perl para executar um dado script. a Veja tambm a documentaao de use VERSION; e de require VERSION; para saber e c como terminar a interpretaao se o Perl estiver desactualizado. O uso desta varivel c a desaconselhado. e 36

$OSNAME, $^O O nome do sistema operativo no qual a actual cpia do Perl foi compilada, o conforme determinado na conguraao de compilaao. Veja o interruptor -V no c c manual perlrun. $EXCEPTIONS BEING CAUGHT, $^S Actual estado de execuao do interpretador. No denido se o parsing do actual c a module/eval no foi completado. Verdadeiro dentro de um bloco eval(), falso fora a dele. $BASETIME, $^T O instante de tempo em que o programa comeou a execuao, em segundos, desde a c c poca (in de 1970). Os valores devolvidos pelos testes a cheiros -M, -A, e -C so e cio a baseados neste valor. $PERL VERSION, $^V Informaao sobre a verso, a subverso e a reviso do Perl que est a ser usada. c a a a a $WARNING, $^W O actual valor do interruptor de avisos (-w). E true ou false consoante foi usado ou no no comando de invocaao do script. Pode ser modicado no script. a c $EXECUTABLE NAME, $^X O nome do executvel Perl. a $ARGV Contm o nome do actual cheiro em processamento, quando se l argumentos da e e linha de comando utilizando <>. @ARGV O array @ARGV contm os argumentos fornecidos na linha de comando que invocou o e script. $#ARGV igual ao nmero de argumentos menos um, porque $ARGV[0] o e u e primeiro argumento, no o nome do programa. $0 contm o nome do programa. a e @INC O array @INC contm a lista de directorias em que os comandos do EXPR, require, e e use procuram mdulos. Inicialmente, consiste dos argumentos especicados com os o interruptores -I e da localizaao da biblioteca de mdulos nativa do Perl (e.g. c o /usr/local/lib/perl seguido de ., a actual directoria). Se fr necessrio alterar o a @INC dentro do script, dever usar-se o pragma use lib para carregar a adequadamente bibliotecas dependentes da mquina: a
use lib /mypath/libdir/; use SomeMod;

@ Dentro de uma subrotina (ou subprograma), o array @ contm os parmetros e a passados para essa subrotina. Consulte a pgina de manual perlsub e a secao a c deste documento, mais adiante, em que se discutem os subprogramas.

37

%INC O hash %INC contm os cheiros inclu e dos com os operadores do, require, ou use. A chave o nome do cheiro especicado (com os nomes dos mdulos convertidos para e o o respectivo path) e o valor guardado no hash %INC indica a localizaao do cheiro. c O operador require usa este hash para determinar se um cheiro j foi inclu a do. %ENV, $ENV{expr} O hash %ENV contm as actuais variveis de sistema. Alterando um valor em %ENV e a altera-se o ambiente de execuao para qualquer processo lho do actual script. c

38

Referncias: princ e pios bsicos a

(Nota: o tratamento das referncias nesta secao segue de perto os manuais perlref e e c perllol ). Em Perl 5 poss utilizar referncias simblicas e referncias fortes (hard). As e vel e o e referncias so variveis escalares. Utilizando arrays e hashes preenchidos com referncias e a a e poss construir estruturas de dados complexas como arrays de arrays, arrays de e vel hashes, hashes de arrays, arrays de hashes de funoes, etc. Nesta secao vai discutir-se c c este tpico, pois estas estruturas so fundamentais em programas que manipulam dados o a com relaoes complexas entre si. c As referncias fortes (obtidas pela prexaao de \ ao e c tem que vo referir) contabilizam a o nmero de vezes que a estrutura referida e dereferida, e fazem recolha de lixo u e (garbage collection) automtica, libertando para posterior utilizaao a memria a c o correspondente `s estruturas que deixam de ser utilizadas. a As referncias simblicas so apenas strings com nomes de variveis ou de outros objectos. e o a a Na prtica, em Perl 5 usa-se quase sempre referncias fortes. a e a E fcil usar referncias em Perl e h apenas uma regra que deve ser sempre seguida: o e a Perl no derefere implicitamente. Se um escalar contm uma referncia, comporta-se a e e como um simples escalar e no se torna, magicamente, no array, hash ou subrotina que a refere. Ele tem que ser de-referido explicitamente para se atingir o objecto apontado.

4.1

Criao de referncias ca e

Criam-se referncias atravs de vrios mtodos. e e a e 1. Usando o operador \ numa varivel, subrotina ou valor. Eis exemplos: a
$escalarref = \$foo; $arrayref = \@ARGV; $hashref = \%ENV; $coderef = \&handler;

Referncias para lehandles so mais complexas de realizar, embora isso possa ser e a feito. 2. Uma referncia para um array annimo pode ser criada com parntesis rectos: e o e $arrayref = [1, 2, 3, [a, b, c]]; Criou-se uma referncia para um array annimo de quatro elementos, cujo ultimo e o elemento tambm uma referncia para um array annimo com trs elementos. A e e e o e sintaxe de acesso a este array multidimensional annimo exemplicada por o e $arrayref->[2][1] que tem o valor b. Referir uma lista enumerada no o mesmo que usar parntesis rectos pelo a e e contrrio, corresponde a criar uma lista de referncias! a e
@lista = (\$a, \@b, \%c); @lista = \($a, @b, %c);

# o mesmo

39

Um caso especial \(@foo) ou \(%foo), que cria uma lista com referncias para e e cada elemento de @foo ou de %foo e no uma referncia para @foo ou &foo. a e 3. Uma referncia para um hash annimo criada com chavetas. e o e
$hashref = { Adam => Eve, Clyde => Bonnie, };

Pode combinar-se arrays e hashes annimos para criar estruturas de dados o complexas. A sintaxe multidimensional funciona sempre. O anterior exemplo utilizou literais, mas pode utilizar-se variveis e expresses como elementos dos a o hashes. Como as chavetas so usadas para delimitar blocos, por vezes necessrio a e a indicar explicitamente ao Perl que a chaveta no marca o in de um bloco, a cio antecedendo-a de + ou de return. Por exemplo, se se pretendesse escrever uma funao que criasse um novo hash e devolvesse a respectiva referncia, t c e nhamos 3 opoes (uma delas errada): c
sub rethashref { { @_ } } sub rethashref { +{ @_ } } sub rethashref { return { @_ } } # errada: o perl v^ um bloco... e # ok: +{ desambigua # ok: return desambigua

Se se pretender, de facto, um bloco, pode-se fazer:


sub retarray { { @_ } } sub retarray { {; @_ } } sub retarray { { return @_ } } # ambguo (actualmente ok, mas...) # ok # ok

Os termos +{ e {; servem para remover a ambiguidade na interpretaao da chaveta, c relativamente a ser considerada como uma referncia para hash ou apenas como e delimitadora de um bloco. 4. Uma referncia para uma subrotina annima criada utilizando o termo sub sem e o e atribuir nome ` subrotina: a $coderef = sub { print "Boink!\n" }; Note que tem que ser colocado um ponto-e-v rgula. Nesta criaao o cdigo da c o subrotina no executado. a e 5. As referncias podem ser devolvidas por subrotinas especiais denominadas e construtores. Esta tcnica de criaao de referncias relaciona-se com OOP e no e c e a e aqui discutida. 6. Uma referncia pode ser criada com uma sintaxe especial, carinhosamente e denominada sintaxe *foo{THING}. *foo{THING} devolve uma referncia para o e tipo THING em *foo (que a denominaao do campo da tabela de s e c mbolos do Perl que engloba todos os nomes foo: @foo, $foo, %foo...)

40

$scalarref $arrayref $hashref $coderef $ioref $globref

= = = = = =

*foo{SCALAR}; *ARGV{ARRAY}; *ENV{HASH}; *handler{CODE}; *STDIN{IO}; *foo{GLOB};

*STDIN{IO} relaciona-se com o acesso a entidades exteriores (lehandles, dirhandles, sockets). *foo{THING} devolve undef se a THING em questo ainda no foi utilizada, a a excepto no caso de escalares pois *foo{SCALAR} devolve uma referncia para um e escalar annimo se $foo ainda no existe. o a

4.2

Utilizao de referncias ca e

H vrios mtodos de utilizaao de referncias. a a e c e 1. Onde poss colocar um identicador (ou cadeia de identicadores), pode-se e vel utilizar uma varivel escalar contendo uma referncia para o tipo correcto: a e
$bar = $$escalarref; push(@$arrayref, $filename); $$arrayref[0] = "Janeiro"; $$hashref{"KEY"} = "VALOR"; &$coderef(1,2,3); print $globref "output\n";

E importante compreender que nestes exemplos no se est a dereferir a a $arrayref[0] ou $hashref{"KEY"}. A dereferncia da varivel escalar acontece e a antes do acesso aos elementos dos arrays ou hashes. Referncias mais complexas, e devero utilizar os mtodos 2 e 3 que se seguem. a e 2. Um identicador pode-se ser substitu por um BLOCO de cdigo que devolve uma do o referncia do tipo correcto. Por outras palavras, os anteriores exemplos poderiam e ser escritos como:
$bar = ${$escalarref}; push(@{$arrayref}, $filename); ${$arrayref}[0] = "Janeiro"; ${$hashref}{"KEY"} = "VALOR"; &{$coderef}(1,2,3); $globref->print("output\n"); # se se utilizar o mdulo IO::Handle o

Nestes exemplos simples exagerado utilizar {...}, mas o BLOCO pode conter e expresses arbitrrias, em particular expresses indexadas como, por exemplo: o a o &{ $dispatch{$index} }(1,2,3); # chama a subrotina correcta A omisso de {...} nos casos simples no causa confuses. Veja, porm, os a a o e seguintes casos, onde o caso 0 uma simplicaao do caso 1, no do caso 2: e c a 41

$$hashref{"KEY"} = ${$hashref}{"KEY"} = ${$hashref{"KEY"}} = ${$hashref->{"KEY"}}

"VALOR"; "VALOR"; "VALOR"; = "VALOR";

# # # #

CASO CASO CASO CASO

0 1 2 3

O caso 2 enganador na medida em que se acede ao hash denominado %hashref: e no se est a dereferir a referncia $hashref e a aceder ao hash que ela aponta. Isto a a e acontece no caso 3. 3. A chamada de subrotinas e o acesso a elementos de arrays e de hashes to e a frequente (e pode causar tantas confuses) que o Perl disponibiliza uma forma o sintctica aucarada para ser utilizada no anterior caso 2. A de-referncia pode ser a c e implementada com uma seta ->, como se mostra de seguida:
$arrayref->[0] = "Janeiro"; $hashref->{"KEY"} = "VALOR"; $coderef->(1,2,3); # Elemento de array # Elemento de hash # Invocaao de subrotina c~

O lado esquerdo do operador -> pode ser uma expresso que devolve uma a referncia, incluindo uma de-referncia prvia. Note que $array[$x] no o mesmo e e e a e que $array->[$x]: $array[$x]->{"foo"}->[0] = "Janeiro"; Este um dos casos em que referncias podem ser criadas num contexto de lvalue e e (left value, i.e., aparecem ` esquerda de um operador). Antes desta instruao, a c $array[$x] poderia estar indenido. Se assim fosse, seria automaticamente criado e preenchido com uma referncia para um hash para que se pudesse procurar {"foo"} e nele. Da mesma forma, $array[$x]->{"foo"} seria automaticamente denido como uma referncia para array de forma a ser poss procurar [0]. Este processo e vel chamado auto-vivicaao. e c O operador -> de utilizaao opcional entre parntesis contendo e c e ndices. Assim, pode compactar-se a anterior instruao para c $array[$x]{"foo"}[0] = "Janeiro"; Quando se usam apenas arrays, esta sintaxe permite referir arrays multidimensionais como feito em em C: e $score[$x][$y][$z] += 42; Bem, OK, no inteiramente como em C. O C no sabe aumentar automaticamente a a um array quando isso lhe pedido, e o Perl sabe 8-). e A utilizaao de uma string ou de um nmero como referncia, cria uma referncia c u e e simblica. A utilizaao de uma referncia como se de nmero se tratasse, devolve um o c e u nmero que representa a posiao de memria apontada. A unica tarefa util que pode ser u c o realizada com este comportamento, a comparaao numrica entre referncias, para saber e c e e se apontam para uma mesma localizaao. c
if ($ref1 == $ref2) { # comparaao numrica de refer^ncias c~ e e print "as refs 1 e 2 referem o mesmo objecto\n"; }

42

A utilizaao de uma referncia em contexto de string, devolve o seu tipo e o respectivo c e endereo numrico em caracteres hexadecimais. O operador ref($umaref) devolve c e apenas o tipo apontado pela referncia $umaref sem o endereo. e c Um typeglob pode ser dereferido da mesma forma que uma referncia, porque a sintaxe e de dereferncia indica sempre o tipo de referncia desejada. Assim, ${*foo} e ${\$foo} e e indicam ambas a mesma varivel escalar $foo. a Eis um truque para interpolar uma chamada de subrotina numa string: print "A sub devolveu @{[mysub(1,2,3)]} agora.\n"; Isto funciona do seguinte modo: quando @{...} encontrado na string entre aspas e (interpolada), executado como um bloco. O bloco cria uma referncia para um array e e annimo contendo o resultado da chamada a mysub(1,2,3). Assim, o bloco global o devolve uma referncia para um array, inserido na string, que dereferido por @{...}. e e Esta aldrabice tambm util para embeber expresses arbitrrias em strings: e e o a print "Chegaram @{[$n + 5]} bruxas\n";

4.3

Referncias Simblicas e o

Disse-se que as referncias so criadas quando necessrio, se no estiverem ainda e a a a denidas, mas no se disse o que acontece se um valor utilizado como referncia j est a e a a denido mas no , de facto, uma referncia forte (hard). Ele ir ser tratado como uma a e e a referncia simblica: o valor do escalar assumido como um nome de varivel: e o e a
$name = "foo"; $$name = 1; ${$name} = 2; ${$name x 2} = 3; $name->[0] = 4; @$name = (); &$name();

# # # # # #

Atribui 1 a $foo Atribui 2 a $foo Atribui 3 a $foofoo Atribui 4 a $foo[0] Esvazia @foo Chama &foo() (como se fazia no Perl 4)

Esta sintaxe poderosa, mas perigosa, pois poss pretender utilizar-se uma referncia e e vel e forte e, acidentalmente, implementar uma referncia simblica. Para prevenir estes erros e o pode ser invocado o pragma use strict refs; e, assim, somente referncias fortes sero admitidas no actual bloco. Num outro bloco e a poder ser alterarada esta restriao com o pragma a c no strict refs; Somente as variveis globais so vis a a veis com referncias simblicas. As variveis lxicas e o a e (declaradas com my()) no entram na tabela de s a mbolos e, por isso, so invis a veis a este mecanismo. Por exemplo:
local $value = 10; $ref = "value"; { my $value = 20; print $$ref;

43

imprime 10 e no 20, pois a declaraao da varivel $value com local() funciona como a c a declaraao de varivel global neste caso. c a

44

Processamento condicional e iterativo

O Perl possui operadores de selecao (processamento condicional) e de iteraao. Antes de c c passar ` sua anlise, vejamos o que e o que no verdadeiro em Perl. a a e a e Qualquer string verdadeira, excepto "" e "0". e Qualquer nmero verdadeiro excepto 0. u e Qualquer referncia verdadeira. e e Qualquer valor indenido falso. e H comportamentos aparentemente estranhos na aplicaao destas regras. Por exemplo, o a c nmero 0.00 considerado falso, mas a string "0.00" considerada verdadeira ( uma u e e e string diferente de "0"). Porm, "0.00"+0 uma operaao que tem como resultado o e e c escalar 0 que considerado falso: assim, "0.00"+0 uma expresso cujo teste lgico e e a o e falso.

5.1

Seleco e processamento condicional ca

O Perl possui a estrutura de selecao condicional if {...} elsif {...} ... elsif {...} c else {...} mas no suporta a construao case existente noutras linguagens. O nmero a c u de clusulas elsif no tem limite. Vejamos um exemplo. a a
if ($idade < 0) { print "Erro!\n"; } elsif ($idade < 3) { print "Bb!\n"; e e } elsif ($idade > 70) { print "Boa, av^!\n"; o } else { print "Pague o imposto!\n"; }

Existe a instruao unless que o complemento lgico de if. As instruoes que se seguem c e o c so equivalentes: a
if ($idade < 0) { print "Erro!\n"; } # equivalente a e unless ($idade >= 0) { print "Erro!\n"; }

Ou seja, if (condition) {...} equivale a unless (not condition) {...}. A construao unless no tem clusulas equivalentes ao else e ao elsif. c a a

45

5.2

Iterao ca

As estruturas de iteraao em Perl so muito usadas no processamento de listas. c a Comea-se pelo while, que habitualmente utilizado da seguinte forma: c e
while (COND) { ...... # algures, numa execuao deste bloco, COND torna-se falsa c~ ...... } # continua aqui, aps COND ser falsa o

Quando se processa o while, a condiao COND avaliada: se fr falsa, o programa c e o continua a execuao aps o bloco while; se fr verdadeira, o bloco while (entre o par de c o o chavetas) executado at ao m. No nal de cada execuao, volta-se ao in e testa-se a e e c cio condiao COND: se fr verdadeira executa-se de novo o bloco; se fr falsa, sai-se do bloco e c o o a execuao continua abaixo. c Pode alterar-se a sequncia de execuao dentro do bloco while usando next, redo e last e c (veja a utilizaao equivalente destas instruoes numa iteraao for, mais abaixo). c c c O while pode ser seguido, opcionalmente, de um bloco continue,
while (COND) { ...... # algures, numa execuao deste bloco, COND torna-se falsa c~ ...... } continue { ...... }

O bloco continue sempre executado, mesmo se a sequncia de processamento dentro do e e while fr alterada devido, por exemplo, a uma instruao next. O continue raramente o c e utilizado. O while serve para processar listas e cheiros. Por exemplo, o cdigo o
while ($line = <CIRCUITO>) { # processa $line... }

l, em cada execuao do bloco interior ao while, uma linha do cheiro apontado pelo e c lehandle CIRCUITO e processa-a, at ser atingido o m do cheiro, onde a condiao e c ($line = <CIRCUITO>) falsa e o while termina. Outro exemplo : e e
while (@ARGV) { # processa(shift @ARGV); }

em que se processa os elementos de @ARGV at este car vazio (shift remove e devolve o e primeiro elemento de @ARGV cada vez que executado). Em while (@ARGV) o array e e 46

avaliado em contexto escalar e devolve o nmero de elementos ( equivalente a while u e (scalar(@ARGV))). Assim, esta condiao falsa se @ARGV estiver vazio. c e Existe tambm a instruao until que funciona de forma anloga ao while excepto no e c a pormenor de que o bloco s executado se a condiao de teste fr falsa: oe c o
while (COND) { .... } # equivalente a e until (!COND) { .... }

# ! o operador de negaao e c~

Neste exemplo
$c = 10; while ($c--) { print $c, ; } print "\n"; $c = 10; until (!$c--) { print $c, ; } print "\n";

ambos os ciclos while e until imprimem 9 8 7 6 5 4 3 2 1 0. A instruao for em Perl bastante semelhante `quela disponibilizada em C. As c e a instruoes de controle next, last e redo permitem alterar a sequncia de processamento c e dentro de ciclos for. Eis o prottipo da sua utilizaao: o c
for (EXPRINIT ; COND ; EXPRMOD) { # CONDREDO transfere a execuao para aqui, o incio do bloco, sem ser testada COND c~ ....... next if CONDNEXT ; ....... last if CONDLAST ; ....... redo if CONDREDO; ....... # CONDNEXT transfere a execuao para aqui, o fim do bloco... c~ } # CONDLAST termina o bloco, e o programa continua aqui...

O ciclo for faz uso de trs expresses. No comeo do ciclo, executa a expresso inicial e o c a EXPRINIT e verica se a condiao COND verdadeira. Se fr, executa o corpo do ciclo c e o (entre chavetas) at ao m, aps o que executa a expresso EXPRMOD que modica a e o a varivel de ciclo testada em COND. De seguida, testa COND e consoante esta seja verdadeira a ou falsa, assim repete ou no a execuao do bloco. a c Na execuao do bloco, se CONDNEXT fr verdadeira a execuao passa para o m do bloco, c o c curto-circuitando todas as instruoes aps next if CONDNEXT;. Se CONDLAST fr c o o verdadeira, a execuao transferida para fora do bloco e o programa continua a ser c e executado a partir da Finalmente, se CONDREDO fr verdadeira, transfere-se a execuao . o c 47

para o cdigo que se segue ` instruao for sem testar a condiao COND. Quando usadas o a c c dentro de uma estrutura iterativa while, o comportamento destas instruoes de controle c e semelhante. A ordem pela qual aparecem next, last e redo no bloco livre. e A instruao continue associada ao while permite fazer uma equivalncia exacta entre c e um for e um while, como se ilustra de seguida:
for ($i = 1; $i < 10; $i++) { ...... } # equivale a $i = 1; while ($i < 10) { ...... } continue { $i++; }

Sem a continue no seria poss a equivalncia exacta entre o for e o while. a vel e Para sair de dentro de vrios ciclos encadeados, usam-se LABELS. Veja o exemplo: a
...... LABELFOR: for ($i=0; $i<= $#myarr; $i++) { ...... $val = $myarr[$i]; ...... LABELWHILE: while ($val !~ /x/) { ...... next LABELFOR if COND1 ; ...... last if COND2 ; # ou last LABELWHILE if COND2 ...... last LABELFOR if COND3 ; ...... next if COND4 ; # ou next LABELWHILE if COND4 ...... # COND4 transfere a execuao para o fim do bloco while c~ } # COND2 termina o bloco while ...... # COND3 transfere a execuao para o fim do bloco for c~ } # COND3 termina ambos os blocos e o programa continua aqui...

Neste cdigo ct o cio, examinam-se os elementos do array @myarr e executa-se um ciclo while quando um elemento contiver a letra x. Dentro deste bloco, vrias condioes a c transferem o processamento para o m ou para fora de um ou dos dois blocos (veja os comentrios no cdigo). As LABELS tambm so utilizadas com a instruao goto. a o e a c Uma construao iterativa muito utilizada em Perl, que no existe em C, foreach $var c a e LISTA. Esta instruao itera nos elementos da lista atribuindo ` varivel escalar $var um c a a elemento da lista de cada vez, e executando depois o bloco associado ao foreach. Note 48

que $var varre os elementos do array e no os a ndices! Se $var fr omitida, usada $ o e na iteraao. Num script t c pico, mais comum foreach do que o for. Vejamos um e exemplo.
foreach $key (sort keys %myhash) { # processa os elementos do hash %myhash por ordem alfabtica e &processa($myhash{$key}); }

Se se zer uma atribuiao ` varivel de iteraao do foreach, como por exemplo em c a a c foreach $j (@lista) { ... $j = algo; ...}, vai-se modicar a prpria lista pois o $j uma referncia para cada elemento da lista. e e As instruoes de iteraao so muito utilizadas nas linguagens de progamaao, e o Perl no c c a c a excepao. J vimos o while a ler cheiros linha a linha, mas esta operaao tambm e c a c e pode ser feita caracter a caracter. O exemplo seguinte utiliza until:
open MYFILE, "bytes.txt"; $buffer = ""; until (eof(MYFILE)) { $buffer = join , $buffer, getc(MYFILE); # mais eficiente que $buffer .= getc(MYFILE) ; e print "$buffer\n" if !eof(MYFILE); }

5.3

Modicadores

Pode efectuar-se processamento condicional e iteraao utilizando if, unless, while e c ` until como modicadores. As vezes esta forma mais elegante e leg e vel. A forma geral dos modicadores : e
if EXPR unless EXPR while EXPR until EXPR

Por exemplo, bastante leg o seguinte cdigo (escrito em Ingls para concordar com os e vel o e modicadores...):
&kiss_me() if $you_like_me; $my_age = 30 unless &you_know_me(); $age++ while $age < 50; $string .= "x" until length $string >= 20;

Se se pretender processar com modicadores um bloco de vrias instruoes, recorre-se ` a c a estrutura do {BLOCO}:
do { instr1; instr2; ....... } [if|unless|while|until] COND;

49

onde, na ultima linha, seleccionado um modicador de entre os 4 poss e veis.

5.4

Goto

O Perl implementa o famigerado goto em trs variedades: goto LABEL, goto EXPR, e e goto &NAME (esta ultima no vai ser discutida). a A instruao goto LABEL tranfere incondicionalmente a execuao do script para a c c instruao etiquetada LABEL: instr. Na segunda variedade, a expresso EXPR devolve o c a nome de uma LABEL, tratando-se de uma generalizaao da anterior. Esta forma permite c implementar gotos calculados (como no Fortran) do gnero de: e
goto ("EMBORA", "CASA", "JANTAR")[$i];

em que, consoante o valor de $i, se segue para um dos destinos (i.e, labels) na lista.

50

Subprogramas, subrotinas ou funoes c

No Perl no h distinao entre subrotinas (ou rotinas), subprogramas e funoes. E a a c c costume denominar-se estas entidades, indiferenciadamente, por qualquer daqueles nomes. Pode criar-se uma subrotina (no exemplo, denominada subnome) em Perl de duas maneiras:
sub subnome { bloco } sub subnome (proto) { bloco }

Na segunda forma, utiliza-se um prottipo (proto) para restringir o tipo e o nmero de o u argumentos fornecidos ` subrotina. Se isso no fr feito, o Perl aceita qualquer coisa! a a o bloco um bloco de cdigo que constitui o corpo da subrotina. Os prottipos s so e o o o a vericados se a funao fr invocada de determinada maneira (se quiser saber os detalhes c o consulte o manual perlsub). Podem ser criadas subrotinas annimas usando referncias o e $refsub = sub { bloco } ; # esta subrotina n~o tem nome a e invoc-las como a %$refsub(args); onde args so os eventuais argumentos. a Para criar uma funao factorial (denominada fact.pl) basta criar o seguinte script: c
# invocado como perl fact.pl num calcula num! print factorial(shift); sub factorial { $_[0] < 2 ? 1 : $_[0] * factorial($_[0]-1); }

O n superior de execuao deste script, muitas vezes denominado main por inuncia vel c e do C, contm uma unica instruao: print. Disse-se, mais atrs, que as funoes so e c a c a invocadas com um nome comeado por & mas isso no exactamante verdade: se a funao c a e c invocada tiver argumentos (como o caso de factorial()) o Perl dispensa o & na e invocaao. Se a funao no tiver argumentos, obrigatrio utilizar o prexo &. c c a e o O que faz o shift no script? O shift tem um comportamento mgico quando invocado a e sem argumento: no n main do script (i.e., fora de qualquer subrotina) aplica-se por vel defeito ao vector @ARGV; dentro duma subrotina, aplica-se por defeito ao vector @ (que tem um papel especial no interior de subotinas, como se ver). Conclui-se que a linha a print... equivalente a e
print factorial(shift @ARGV);

ou, ainda a:
print factorial($ARGV[0]);

Vamos discutir agora o subprograma factorial. Um subprograma/funao em Perl pode c ser denido/declarado em qualquer parte do script. Poder-se-ia ter escrito primeiro a funao factorial e invoc-la depois. c a No vis a declaraao de argumentos na funao pois, implicitamente, os argumentos a e vel c c so passados para dentro da funao atravs do array @ pela mesma ordem em que a c e 51

aparecem na invocaao da funao. No presente caso, temos apenas um argumento escalar, c c que passado para a primeira posiao de @ , o escalar $_[0]. Este array @ tem uma e c cpia local em cada subprograma: pode-se invocar rotinas dentro de rotinas alis, o a neste caso factorial() uma funao recursiva invocada n vezes , pois criam-se e c cpias locais de @ em cada invocaao. o c A unica instruao na funao o operador ternrio de selecao condicional, cujo prottipo c c e a c o cond ? instr yes : instr no;. Se a condiao cond fr verdadeira, executada a e c o e instruao instr yes e, se no fr, executada instr no. J se ver a utilizaao do c a o e a a c operador if como alternativa a este operador. A funao factorial que denimos m c e nima pois no faz qualquer vericaao de erros e a c aceita alegremente argumentos negativos, no inteiros, ou no existentes. Veja a mesma a a funao escrita de uma forma mais clara: c
sub factorial { my($n) = shift @_; # ou my($n) = $_[0]; if ($n < 2) { return 1; } else { return $n * &factorial($n-1); } } print &factorial($ARGV[0]);

Nesta verso para iniciados 8-) tudo claro! Temos um if e temos a instruao return a e c que nos faz chorar de saudade do C! Na anterior verso para prossionais no existia a a instruao return: em Perl, um subprograma devolve o ultimo valor/objecto que calculou c (pode devolver um array ou um hash, por exemplo). Uma funao que devolve um array terminar da seguinte forma: c a
sub devolve_array { ............ @array_que_sai; }

# o mesmo que return @array_que_sai

Obviamente, este subprograma poderia devolver um escalar $escalar ou um hash %hash, terminando a execuao com a simples invocaao do objecto. Um subprograma pode ter c c mltiplas sa u das como acontece com a funao factorial. c

6.1

Variveis locais a

Quando se mencionam variveis novas num subprograma, elas so criadas como variveis a a a globais. Isto signica que vo car para sempre a ocupar memria de sistema, mesmo a o que o subprograma seja executado uma unica vez. Por vezes, pretende evitar-se este comportamento, no s para economizar memria como tambm para evitar colises a o o e o entre variveis utilizadas em blocos de cdigo separados por milhares de linhas, o que a o acontece em projectos da vida real 8-).

52

Para declarar variveis localmente, dentro de subprogramas ou de blocos, o Perl dispe de a o duas instruoes de declaraao: my e local. c c my declara as variveis como privadas dentro do bloco (o jargo tcnico lexically a a e e scoped). Elas so suprimidas quando termina a execuao do bloco/subrotina e so a c a invis veis em qualquer outro ponto do programa. Por outro lado, local usado para declarar variveis dinmicas. Estas variveis no so e a a a a a privadas do bloco, mas sim variveis globais com valores locais. Quando a subrotina a e executada o valor global escondido e utilizado o valor local. As variveis declaradas com e a local so vis a veis em subrotinas invocadas de dentro do bloco/subrotina onde foram declaradas. Veja-se o seguinte exemplo, onde se ilustra a diferena entre my e local.. c
$a = "a_global"; &printa; &submy; &subloc; # varivel global a # 1a invocaao c~

sub submy { my $a = "a_my"; &printa; # 2a invocaao c~ } sub subloc { local $a = "a_local"; &printa; # 3a invocaao c~ } sub printa { print $a , "\n"; }

# imprime a varivel $a visvel em printa a

A execuao deste programa d o seguinte resultado: c a


a_global a_global a_local

que conrma aquilo que se disse. A 1a invocaao imprime obviamente a varivel global. A c a 2a invocaao feita de dentro de submy onde se declarou localmente $a com my e que, c e portanto, s existe dentro desta subrotina submy: assim, o subprograma printa v a o e c e varivel $a global e imprime a global. Finalmente, a 3a invocaao feita dentro de a subloc que declarou localmente $a com local e, assim, torna vis este $a em todas as vel subrotinas invocadas no corpo da subrotina subloc: consequentemente, printa v a e varivel $a declarada com local e imprime a local. a Na prtica, o que normalmente se pretende com a utilizaao de variveis locais o a c a e comportamento associado ` declaraao my, pelo que esta a mais utilizada. a c e

6.2

Passagem de argumentos para subrotinas

Para melhorar a legibilidade do cdigo, costuma fazer-se uma cpia para variveis locais o o a e c do array @ que contm os argumentos passados para a funao. Quando se pretende 53

passar para dentro do subprograma um ou mais arrays juntamente com outras variveis, a e preciso ter algum cuidado. Suponha que se criaram as seguintes variveis a
$e1 $e2 @a1 @a2 %h = = = = = 10.0; boo; (1,2,3,4); (a,b,c); (alfa => romeo, land => rover);

e que se pretende envi-las como argumentos para uma funao denominada subprog. Veja a c o seguinte bloco de poss veis invocaoes (numeradas articialmente) e os respectivos c comentrios (onde o s a mbolo <- signica recebe ou ca igual a).
# ((1)) &subprog($e1,$e2); ....................... sub subprog { my ($a,$b) = @_; # Correcto: $a <- $e1 e $b <- $e2 ....................... # ((2)) &subprog($e1,@a1); ....................... sub subprog { my ($a,@b) = @_; # Correcto: $a <- $e1 e @b <- @a1 ....................... # ((3)) &subprog($e1,%h); ....................... sub subprog { my ($a,%b) = @_; # Correcto: $a <- $e1 e %b <- %h ....................... # ((4)) &subprog(@a1,$e1); ....................... sub subprog { my (@a,$b) = @_; # Incorrecto: @a <- (@a1,$b) e $b <- ....................... # ((5)) &subprog(@a1,@a2); ....................... sub subprog { my (@a,@b) = @_; # Incorrecto: @a <- (@a1,@a2) e @b <- () ....................... # ((6)) &subprog(%h,@a1); ....................... sub subprog { my (%a,@b) = @_; # Incorrecto: %a <- (%h,@a1) e @b <- ()

54

.......................

Como vis nos exemplos ((4)), ((5)) e ((6)), quando a primeira varivel a recolher e vel a argumentos no my() uma lista, ir engolir todo o vector @ . Para resolver este e a problema, usam-se referncias (que so escalares), pois com argumentos escalares no h e a a a problema. Veja os exemplos ((4)) e ((5)) corrigidos com referncias: e
# ((4)) &subprog(\@a1,$e1); ....................... sub subprog { my ($a,$b) = @_; @a = @$a; ....................... # ((5)) &subprog(\@a1,\@a2); ....................... sub subprog { my ($a,$b) = @_; @a = @$a; @b = @{$b}; .......................

# Correcto: $a <- \@a1 e $b <- $e1 # De-refere-se $a=\@a1

# Correcto: $a <- \@a1 e $b <- \@a2 # De-refere-se # De-refere-se com chavetas para clarificar...

Bem, j foi revista a matria mais importante relacionada com subprogramas. Vamos a e agora discutir a execuao de cdigo on-the-y (i.e., imediatamente), cdigo esse c o o eventualmente criado durante a execuao do prprio script. c o

55

Execuo de cdigo em run-time: eval e require ca o

Uma das vantagens das linguagens interpretadas que se pode escrever cdigo durante a e o execuao de um script e utiliz-lo imediatamente. O Perl possui a funao eval para c a c executar cdigo escrito numa string. O mesmo pode ser conseguido com a escrita de o cdigo num cheiro externo que executado com require ou use. Adicionalmente, eval o e o mecanismo existente no Perl que permite lidar com excepoes. Examine o seguinte e c script (denominado m.pl.)
$a = 10 ; $b = 0 ; $c = $a / $b ; print $a, $b, $c ;

Quando executado, este script termina prematuramente com o erro Illegal division by zero at m.pl line 3. pois uma diviso por zero uma excepao sucientemente grave para abortar o programa. a e c Como que se pode testar, num bloco de cdigo, a diviso por zero ou, em termos gerais, e o a qualquer outra operaao ilegal, sem abortar o script? Usando eval, pois claro! c Dentro do eval o cdigo executado numa redoma: se no houver qualquer erro, aps a o e a o sua execuao a varivel $@ igual ` string nula ; se houver erro, esta varivel contm uma c a e a a e string com a mensagem de erro. Este processo permite lidar com excepoes. Observe c como poderia proteger o anterior bloco de cdigo com eval: o
$a = 10 ; $b = 0 ; eval {$c = $a / $b}; # ou eval $c = $a / $b; $c="infty" if $@; print "a=$a b=$b c=$c\n";

Quando executado, este script escreve na consola a=10

b=0

c=infty.

A diviso por zero executada dentro do eval; como h erro, escrita a respectiva a e a e mensagem de erro em $@ que, quando testada aps o eval, a uma condiao verdadeira e o e c (se no tivesse havido qualquer erro, $@= era falsa). Ento, executa-se a atribuiao a a c $c="infty", o valor imprimido no nal. Note que a execuao do script no foi c a interrompida pelo erro dentro do eval. A funao eval pode ser utilizada de duas maneiras: c eval BLOCO eval EXPR A principal diferena que o uso do BLOCO (cdigo entre chavetas) mais eciente do que c e o e o uso da expresso EXPR, pois o bloco s compilado uma vez: esta forma deve ser sempre a oe utilizada se o cdigo embebido na string no variar. No anterior script qualquer das o a formas poderia ter sido utilizada (a expresso eval $c = $a / $b; est comentada). a a Pode aplicar eval a uma varivel escalar de duas formas equivalentes: a $s = $c = $a / $b eval $s; 56

eval "$s";

# forma equivalente

Veja agora um exemplo que mostra como escrever cdigo num cheiro externo e proceder o ` sua execuao imediata no mesmo script. a c
open(CUBO,">cubo.pl") || die n~o posso abrir cubo.pl!\n ; a print CUBO sub cubo { $_[0] ** 3 } 1 ; # escreve um subprograma no ficheiro close CUBO ; require cubo.pl ; # executa cubo.pl # eval type cubo.pl ; # em Windows # eval cat cubo.pl ; # em Unix/Linux # eval qx/type cubo.pl/ ; # em Windows # eval qx/cat cubo.pl/ ; # em Unix/Linux # NOTA: quando se usa eval n~o necessrio terminar cubo.pl com 1 a e a print cubo(10), "\n" ; # imprime 1000

Abre-se o cheiro cubo.pl e este associado ao lehandle CUBO onde escrita a subrotina e e cubo. Repare que escrito 1 no m deste cheiro, para que o valor lgico devolvido por e o require seja verdadeiro: qualquer nmero ou string diferentes de 0 ou de "" (a string u nula) poderia ter sido usado em vez do 1. Aps o cheiro ser processado com require, todas as suas variveis e subprogramas cam o a vis veis no actual contexto, como se tivessem sido escritos no actual script. Pode-se realizar a mesma tarefa com eval, utilizando a forma especial de string com acentos graves comando (ou qx/comando/) que executa o comando de sistema e devolve o resultado. O resultado da execuao de um type ou de um cat (em Unix/Linux) a c e listagem do cheiro, que ento processado pelo eval. Isto equivalente a uma invocaao e a e c com require. Se se utilizar eval, ca-se dispensado de colocar um valor verdadeiro no m do cheiro (1, no caso de cubo.pl). Finalmente, h formas bem mais sosticadas de utilizar cdigo escrito em cheiros a o externos. Veja as instruoes/declaraoes use, import, package e do . Estude tambm c c e programaao orientada para objectos em Perl. c Vamos passar agora para algo completamente diferente (isto uma piada aos Monty e Python): as expresses regulares. o

57

Expresses regulares (regexes) o

Um dos pontos fortes do Perl, que justica parcialmente a sua popularidade, a sua e excelncia no processamento de texto. Essa excelncia est intimamente ligada ao suporte e e a de expresses regulares embebido na linguagem e ` qualidade do respectivo motor o a (regex engine). E frequente referir as expresses regulares apenas por regex ou regexp o (plural regexes ou regexps). Nas expresses regulares podem utilizar-se caracteres e metacaracteres. Os caracteres o ordinrios so intrepretados como eles prprios. Os metacaracteres tm um signicado a a o e especial. Em particular, os seguintes metacaracteres tm o seguinte comportamento e (semelhante `quele encontrado nas expresses regulares da ferramenta egrep em sistemas a o Unix). Metacaracter \ ^ . $ | () [] Signicado Escapa (ou cita) o prximo caracter ou metacaracter o Acerta no princ pio da linha Acerta em qualquer caracter (excepto em newline \n) Acerta no m da linha (ou antes de \n no m) Alternncia a Agrupamento Classe de caracteres

Por defeito, o caracter "^" s acerta no in da string e o caracter "$" no m (ou antes o cio do \n no m). Caracteres \n no so atingidos por "^" ou por "$". Pode-se, no a a entanto, tratar a string como se tivesse vrias linhas utilizando o modicador /m no m a da regex. Veja, mais abaixo, a deniao destes modicadores. c Para simplicar as substituioes em mais que uma linha, o caracter "." nunca acerta em c \n a menos que seja usado o modicador /s que diz ao Perl que a string consiste de uma unica linha (mesmo que isso no seja verdade). a So reconhecidos os seguintes quanticadores em regexes: a Quanticador * + ? {n} {n,} {n,m} Signicado Acerta 0 ou mais vezes Acerta 1 ou mais vezes Acerta 1 ou 0 vezes Acerta exactamente n vezes Acerta pelo menos n vezes Acerta pelo menos n mas no mais do que m vezes a

(Se uma chaveta aparece noutro contexto, tratada como um caracter normal.) O e quanticador "*" equivalente a {0,}, o quanticador "+" equivalente a {1,} e o e e quanticador "?" equivalente a {0,1}. e Por defeito, um sub-padro quanticado numa regex ganancioso, pois tenta acertar ((ou a e coincidir) no maior nmero poss de caracteres (numa dada posiao) e simultaneamente u vel c permitir ao restante padro na regex coincidir. Se se pretender que o sub-padro acerte a a um nmero m u nimo de vezes, acrescenta-se ao quanticador ?. O signicado dos quanticadores no muda com o ?, apenas a sua ganncia. a a

58

Quanticador *? +? ?? {n}? {n,}? {n,m}?

Signicado Acerta 0 ou mais vezes Acerta 1 ou mais vezes Acerta 0 ou 1 vez Acerta exactamente n vezes Acerta pelo menos n vezes Acerta pelo menos n mas no mais que m vezes a

Uma vez que os padres so processados como strings interpolveis, os seguintes o a a caracteres especiais so reconhecidos em regexes: a Caracter \t \n \r \f \a \e \033 \x1B \x{263a} \c[ \l \u \L \U \E \Q Signicado tab newline return form feed alarme escape caracter em octal caracter em hexadecimal caracter hexadecimal generalizado caracter control passa prximo caracter a minscula o u passa prximo caracter a maiscula o u minsculas at \E u e maisculas at \E u e m de modicaao \L, \U, \q c inibe metacaracteres at \E e Representao ca (HT, TAB) (LF, NL) (CR) (FF) (BEL) (ESC)

(SMILEY em Unicode)

Adicionalmente, em Perl denem-se as seguintes classes de caracteres (h outras, a relacionadas com a codicaao Unicode): c Classe \w \W \s \S \d \D Signicado Acerta num caracter Acerta num caracter Acerta num caracter Acerta num caracter Acerta num d gito Acerta num caracter de palavra (alfanumricos mais "_") e que no seja de palavra a espao (tab,newline,espao,...) c c que no seja espao a c que no seja d a gito

\w coincide com um unico caracter alfanumrico, no uma palavra. Use \w para acertar e a numa string constitu por identicadores de Perl (diferente de uma palavra em da Portugus, devido aos caracteres acentuados). e \w, \W, \s, \S, \d e \D podem ser utilizadas dentro de classes de caracteres mas no a podem denir o princ pio ou o m de gamas. Veja o operador de transliteraao tr///. c As seguintes armaoes (assertions) de comprimento zero (i.e., no acertam num c a caracter, mas sim na fronteira da string) esto denidas em Perl : a

59

Classe \b \B \A \Z \z

Signicado Acerta numa fronteira de palavra Acerta fora de uma fronteira de palavra Acerta somente no princ pio da string Acerta somente no m da string, ou antes de \n no m Acerta somente no m da string

A fronteira de uma palavra o ponto (imaginrio...) que tem um \w de um lado e um \W e a do outro lado. O in e o m da string so considerados como \W. cio a \A e \Z so como "^" e "$", excepto que no acertam mltiplas vezes quando o a a u modicador /m usado, enquanto que "^" e "$" acertam em fronteiras de linha internas. e Para acertar o verdadeiro m da string e no ignorar o \n que l possa estar use \z. a a A construao com parntesis curvos (...) cria variveis de captura de substrings. Para c e a se referir ` <dgito>-sima destas variveis (por ordem de apariao na regex) usa-se a e a c \<dgito> dentro da mesma regex ou $<dgito> fora da regex. A referncia a uma e anterior coincidncia chama-se retro-referncia (backreference). O limite de e e retro-referncias muito grande. (Nota: o Perl desambigua inteligentemente e e retro-referncias superiores a 9, e.g. a retro-referncia \12 e o mesmo valor como ssia de e e o 012 em octal, que se refere ao 10o caracter ASCII. Consulte o manual). Exemplos:
s/^([^ ]*) *([^ ]*)/$2 $1/; # troca as duas primeiras palavras if (/(.)\1/) { # encontra o primeiro caracter duplo print "$1 o primeiro caracter duplo\n"; e } if (/Tempo: (..):(..):(..)/) { $horas = $1; $minutos = $2; $segundos = $3; } # extrai valores

H variveis especiais relacionadas com regexes. $+ devolve o ultimo acerto com a a parntesis. $& devolve toda a string atingida. $ devolve os caracteres anteriores ` string e a atingida. E $ devolve todos os caracteres posteriores ` string atingida. O uso destas a variveis especiais e de $1, $2, ... atrasa MUITO o processamento das expresses a o regulares no script: use-as somente se delas necessitar. Em Perl os caracteres escapados com \ so sempre alfanumricos. Assim, contruoes a e c como \\, \(, \), \<, \>, \{, ou \} so sempre interpretadas literalmente i.e., no a a tm qualquer signicado especial pois no so metacaracteres. e a a Usa-se a funao quotemeta() ou os escapes \Q...\E para inibir localmente os signicados c especiais dos metacaracteres, da seguinte forma: /$unquoted\Q$quoted\E$unquoted/

60

8.1

Sintaxe ampliada (extended) de expresses regulares o

O Perl suporta uma sintaxe ampliada para expresses regulares que consiste de um par o de parntesis com um ponto de interrogaao como primeiro caracter (?...). O caracter e c que se segue ao ponto de interrogaao indica o tipo da extenso. Consulte a secao c a c Extended Patterns no manual perlre.

8.2

Regras aplicveis em expresses regulares a o

Eis um sumrio das regras que se aplicam em expresses regulares. a o Qualquer caracter simples acerta nele prprio, a menos que seja um metacaracter com o signicado especial. Pode forar-se um metacaracter a ser interpretado literalmente c prexando-o com "\" (e.g., "\." acerta apenas num simples ponto, "\\" acerta em "\", etc). Uma sequncia de caracteres acerta apenas nessa mesma sequncia de caracteres. e e Pode especicar-se uma classe de caracteres encerrando a respectiva lista entre [ ], que assim acertar em qualquer caracter da lista. Se o primeiro caracter aps [ fr "^" a a o o classe acerta em cada caracter que no pertena ` lista (a classe negada). Numa lista, a c a e o caracter "-" especica uma gama de forma que a-z representa todos as letras minsculas. Se se pretender um "-" ou um "[" inclu na classe, deve-se p-lo no in u do o cio da lista (ou aps um "^") ou escap-lo com "\". "-" tambm interpretado literalmente o a e e quando no m duma lista (antes do "]"). Em princ pio, as gamas de caracteres s o devero ser aplicadas a caracteres alfanumricos. a e Certos caracteres podem ser especicados por metacaracteres: \n um newline, \t e um tab, etc. Mais geralmente \nnn, onde nnn uma string de d e e gitos octais, representa o caracter ASCII de valor nnn. De forma semelhante \xnn, onde nn uma string de e d gitos hexadecimais, representa o caracter ASCII de valor nn. A expresso \cx a representa o caracter ASCII control-x. Finalmente, o metacaracter "." acerta em qualquer caracter excepto em \n (a menos que se use o modicador da regex /s). Pode especicar-se alternativas num padro duma regex com "|" a separ-las: assim, a a fee|fie|foe coincide em "fee", em "fie" ou em "foe" na string alvo (assim como a regex equivalente "f(e|i|o)e"). Os delimitadores exteriores das alternativas so a parntesis curvos (e.g. (fee|fie|foe)) e comum adicionar os parntesis para denir e e e com clareza os limites. As alternativas so testadas da esquerda para a direita; a primeira a ser encontrada que a conduz a uma coincidncia da regex a escolhida. e e Dentro de uma classe [...] "|" interpretada literalmente, por forma que e [fee|fie|foe] equivalente a [feio|] (os caracteres repetidos dentro de uma classe no e a interessam).

8.3

Pesquisa, substituio e transliterao ca ca

As expresses regulares podem ser utilizadas em trs funoes importantes: para pesquisar o e c texto, para substituir texto e para transliterar texto (substituir grupos de caracteres directamente por outros). Na exposiao que se segue, PATTERNx (onde x um d c e gito ou no existe) um padro de expresso regular. a e a a

61

m/PATTERN/cgimosx /PATTERN/cgimosx Nesta construao pesquisa-se numa string a regex PATTERN. Em contexto escalar, a c construao d verdadeira se a pesquisa fr bem sucedida e falsa em caso contrrio. c a o a Se no fr especicada uma string com os operadores =~ ou !~, a string $ a o e examinada. A string ` esquerda destes operadores pode ser o resultado de uma a expresso. Na forma m/.../, as barras podem ser substitu a das por outros 2 caracteres no alfanumricos, iguais entre si, ou por um par de parntesis a e e complementares. Exemplos:
if (m[Pedro]i) ... # if ($_ =~ m|Pedro|i) ... # if ($linha !~ /tua/) ... # # verdade se $_ contm pedro ou Pedro ou Pedroso... e equivalente verdade se $linha n~o contm tua a e O m em m/.../ foi omitido

As opoes, ou modicadores, tm o seguinte signicado: c e Modicador c g i m o s x Signicado No faz reset ` posiao de pesquisa num insucesso com /g activo a a c Pesquisa globalmente, i.e., encontra todas as ocorrncias e Pesquisa insens a maiscula/minscula vel u u Trata a string como linhas mltiplas u Compila PATTERN uma unica vez Trata a string como uma unica linha Usa expresses regulares generalizadas ou ampliadas (extended) o

Se o delimitador da regex fr "/", o m inicial pode ser omitido. Especicando o m, o pode utilizar-se qualquer par de caracteres no alfanumricos. Se o delimitador fr a e o "?" , aplica-se a regra acerta-apenas-uma-vez (na forma ?PATTERN?). Se o delimitador fr uma plica "" no feita interpolaao. o a e c PATTERN pode conter variveis, que sero interpoladas (e a regex recompilada) a a excepto quando o delimitador a plica "". Utilizando o modicador /o a e compilaao feita apenas uma vez (poupa-se tempo!): pode ser aplicado quando a c e regex constante. Aqui presume-se que as variveis interpoladas no mudam (se e a a mudaram, o Perl nem d por isso!) Veja tambm qr//. a e Se a opao /g no fr usada, em contexto de lista m// devolve uma lista que consiste c a o das subexpresses encontradas com os parntesis, i.e. ($1, $2, $3...). Se no h o e a a parntesis no padro, o valr devolvido a lista caso a pesquisa seja bem sucedida. e a o e Com ou sem parntesis, aps um insucesso devolvida uma lista vazia. e o e Exemplos:
open(TTY, /dev/tty); <TTY> =~ /^y/i && foo();

# executa foo() se a 1 a condiao f^r verdadeira c~ o # extrai vers~o a

if (/Version: *([0-9.]*)/) { $version = $1; } next if m#^/usr/spool/uucp#; # grep do pobrezinho... $arg = shift;

62

while (<>) { print if /$arg/o; }

# compila apenas uma vez

if (($F1, $F2, $Etc) = ($foo =~ /^(\S+)\s+(\S+)\s*(.*)/))

Este ultimo exemplo parte $foo nas primeiras duas palavras e no resto da linha, e atribui estas 3 peas a $F1, $F2 e $Etc. A condiao verdadeira se qualquer uma c c e das 3 variveis fr atribu a o da. O modicador /g especica globalidade, i.e., acerta tantas vezes quanto as poss veis na string. Em contexto escalar, pode recuperar-se a posiao aps o ultimo acerto c o com a funao pos(). Consulte o manual. c s/PATTERN/REPLACEMENT/egimosx Pesquisa o padro PATTERN numa string e, se o encontra, substitui-o com a REPLACEMENT (substituto). Devolve o nmero de substituioes feitas. Se no u c a substitu nada, devolve a string nula (i.e., uma condiao falsa). u c Se no se especicar uma string com os operadores =~ ou !~, pesquisada e a e modicada a varivel $_. Se especicada, a string deve ser um escalar, elemento de a array ou de hash ou uma atribuiao a um deles. c Se o delimitador fr uma plica, no feita interpolaao nem em PATTERN nem em o a e c REPLACEMENT (o modicador /e altera este comportamento). Com qualquer outro delimitador, se existe um $... que se assemelha a uma varivel, esta ser a a interpolada durante a execuao. O modicador /o compila a regex apenas uma vez, c na primeira interpolaao da varivel. c a Os modicadores so: a Modicador Signicado e Calcula o lado direito como uma expresso a g Substitui globalmente, i.e., substitui todas as ocorrncias e i Pesquisa insens a maiscula/minscula vel u u Trata a string como linhas mltiplas u m o Compila PATTERN uma unica vez s Trata a string como uma unica linha x Usa expresses regulares generalizadas ou ampliadas (extended) o Qualquer caracter no-alfanumrico e no espao, pode substituir os delimitadores a e a c "/". Se PATTERN fr delimitada por parntesis de qualquer tipo, REPLACEMENT o e tambm ganha um par de delimitadores (de qualquer tipo), e.g., s(foo)(bar) ou e s<foo>/bar/. O modicador /e faz com que REPLACEMENT seja tratada como uma expresso Perl que executada. A sua sintaxe vericada logo na compilaao. a e e c Exemplos:
s/\bbom\b/mau/g; $path =~ s|/usr/bin|/usr/local/bin|; s/Login: $foo/Login: $bar/; ($foo = $bar) =~ s/this/that/; $count = ($paragraph =~ s/Mister\b/Mr./g); # n~o substitui bombom... a # regexes construdas na execuao c~ # copia $bar primeiro, depois muda $foo # conta o nmero de substituioes u c~

63

$_ = abc123xyz; s/\d+/$&*2/e; s/\d+/sprintf("%5d",$&)/e; s/\w/$& x 2/eg;

# d abc246xyz a # d abc 246xyz a # d aabbcc 224466xxyyzz a # muda escapes por-cento; sem /e # substitui em cada execuao, com /e c~ # usa chamada a funao c~

s/%(.)/$percent{$1}/g; s/%(.)/$percent{$1} || $&/ge; s/^=(\w+)/&pod($1)/ge;

# expande variveis din^micas em $_ com refer^ncia simblica a a e o s/\$(\w+)/${$1}/g; # Adiciona 1 ao valor de todos os nmeros na string u s/(\d+)/1 + $1/eg; # Apaga comentrios num programa em C. a $program =~ s { /\* # Acerta no delimitador de abertura. .*? # Acerta num nmero mnimo de caracteres. u \*/ # Acerta no delimitador de fecho. } []gsx; s/^\s*(.*?)\s*$/$1/; for ($variable) { s/^\s+//; s/\s+$//; } # retira espaos no incio e no fim de $_, caro c # retira espaos iniciais e finais a $variable, barato c

s/([^ ]*) *([^ ]*)/$2 $1/;

# troca os primeiros dois campos

Note o uso de $ em vez de \ no ultimo exemplo. A forma \<digit> s usada oe no lado esquerdo do operador de substituao: em qualquer outro ponto usa-se c $<digit>. tr/SEARCHLIST/REPLACEMENTLIST/cdsUC y/SEARCHLIST/REPLACEMENTLIST/cdsUC Translitera todas as ocorrncias dos caracteres encontrados na lista SEARCHLIST e com o caracter na posiao correspondente da lista de substituiao c c REPLACEMENTLIST. Devolve o nmero de caracteres substitu u dos ou apagados. Se no fr especicada uma string com os operadores =~ ou !~, transliterada $_. A a o e string a transliterar dever ser um escalar, um elemento de array ou de hash, ou a uma atribuiao a um deles. c Uma gama de caracteres especicada com "-", de forma que tr/A-J/0-9/ o e e mesmo que tr/ACEGIBDFHJ/0246813579/. y sinnimo de tr. Em princ e o pio, dever-se- usar gamas apenas com caracteres alfanumricos e no com outros a e a caracteres (e.g., de pontuaao). c Se SEARCHLIST fr delimitada por qualquer tipo de parntesis, ento o e a REPLACEMENTLIST tem o seu prprio par de delimitadores, que podem ou no ser o a parntesis, e.g., tr[A-Z][a-z] ou tr(+\-*/)/ABCD/. e O signicado dos modicadores de tr/// : e 64

Modicador c d s U C

Signicado Complementa a SEARCHLIST. Apaga caracteres encontrados mas no substitu a dos. Comprime caracteres substitu dos em duplicado. Translitera para/de UTF-8. Translitera para/de caracter de 8 bits (octeto).

Se o modicador /c fr especicado, o conjunto de caracteres em SEARCHLIST o e complementado. Se o modicador /d fr especicado, quaisquer caracteres em o SEARCHLIST no encontrados em REPLACEMENTLIST so apagados. Se o modicador a a /s fr especicado, sequncias de caracteres transliteradas para o mesmo caracter o e so comprimidas para uma unica instncia do caracter. a a Se o modicador /d fr usado, a REPLACEMENTLIST sempre interpretada o e exactamente como especicado. Caso contrrio, se a REPLACEMENTLIST fr mais a o curta que a SEARCHLIST, o ultimo caracter replicado at igualar o tamanho das e e duas listas. Se a REPLACEMENTLIST estiver vazia, a SEARCHLIST replicada. Esta e ultima possibilidade util para contar caracteres duma classe ou para comprimir e sequncias de caracteres numa classe. e Exemplos:
$ARGV[1] =~ tr/A-Z/a-z/; # passa $ARGV[1] para minsculas u $cnt = tr/*/*/; # conta os asteriscos em $_ $cnt = $ceu =~ tr/*/*/; # conta as estrelas no $ceu $cnt = tr/0-9//; # conta os dgitos em $_ tr/a-zA-Z//s; # bookkeeper -> bokeper ($HOST = $host) =~ tr/a-z/A-Z/; tr/a-zA-Z/ /cs; # substitui n~o-alfanumricos por espao a e c tr [\200-\377] [\000-\177]; # apaga o oitavo bit tr/\0-\xFF//CU; # muda Latin-1 para Unicode tr/\0-\x{FF}//UC; # muda Unicode para Latin-1

Se houver mltiplas transliteraoes para um caracter, apenas a primeira utilizada: u c e tr/AAA/XYZ/ translitera qualquer A para X. Uma vez que a tabela de transliteraao constru durante a compilaao, nem a c e da c SEARCHLIST nem a REPLACEMENTLIST so sujeitas a interpolaao de variveis. Isto a c a signica que se se pretender utilizar variveis deve-se usar eval(): a
eval "tr/$oldlist/$newlist/"; die $@ if $@; eval "tr/$oldlist/$newlist/, 1" or die $@;

65

9
9.1

Manipulao de arrays de arrays em Perl ca


Declarao e acesso a arrays de arrays (AoAs) ca

A estrutura de dados composta mais simples de construir o array de arrays. O processo e de criaao simples de compreender e as tcnicas aplicadas so vlidas para estruturas de c e e a a dados mais avanadas. c Um array de arrays um comum array @AoA que pode ser constru implicitamente e do utilizando dois ndices, como $AoA[3][2]. Para construir e preencher explicitamente o array faz-se o seguinte:
# construir um array de refer^ncias para arrays e @AoA = ( [ "fred", "barney" ], [ "george", "jane", "elroy" ], [ "homer", "marge", "bart" ], ); print $AoA[2][2]; # imprime bart

E necessrio ter em atenao que os parntesis externos so curvos, pois estamos a a c e a preencher um @array. Se se pretendesse aceder ao array, anonimamente, atravs de uma e referncia, far-se-ia o seguinte: e
# construir uma refer^ncia para um array de refer^ncias para arrays e e $ref_to_AoA = [ [ "fred", "barney", "pebbles", "bambam", "dino", ], [ "homer", "bart", "marge", "maggie", ], [ "george", "jane", "elroy", "judy", ], ]; print $ref_to_AoA->[2][2]; # imprime elroy

Repare que os parntesis exteriores mudaram para parntesis rectos, e a sintaxe de acesso e e tambm mudou. Em Perl, contrariamente ao C, no se pode utilizar e a indiscriminadamente, como sinnimos, arrays e referncias para arrays. $ref_to_AoA o e e uma referncia para um array enquanto que @AoA mesmo um array. Assim, $AoA[2] no e e a um array mas uma referncia para um array. e e Ento, porque que se escreve a e
$AoA[2][2] $ref_to_AoA->[2][2]

em vez de se escrever
$AoA[2]->[2] $ref_to_AoA->[2]->[2]

Bem, porque existe a regra de que entre parntesis adjacentes (parntesis rectos ou e e chavetas) -se livre de omitir a seta de dereferncia do apontador. Mas a primeira (entre e e o nome do apontador e o primeiro parntesis) no pode ser omitida, o que signica que e a $ref_to_AoA precisa sempre de a utilizar. 66

9.2

Criao dinmica de AoAs ca a

Vimos como se pode criar implicitamente uma estrutura de dados @AoA xa. Vamos ver agora como cri-la e como se pode adicionar-lhe elementos dinamicamente. a Primeiro, vamos ver como se pode l-la de um cheiro, isto , como adicionar uma linha e e de cada vez. Assume-se que h um cheiro cujas linhas iro corresponder a uma linha do a a array, e que cada palavra da linha um elemento. Se se pretende criar um @AoA com o e contedo deste cheiro, eis como faz-lo correctamente: u e
while (<>) { @temp = split; push @AoA, [ @temp ]; }

Tambm se poderia preencher o array com o resultado de uma funao: e c


for $i ( 1 .. 10 ) { $AoA[$i] = [ umafunc($i) ]; }

Ou poder-se-ia utilizar uma varivel temporria para claricar o cdigo: a a o


for $i ( 1 .. 10 ) { @temp = umafunc($i); $AoA[$i] = [ @temp ]; }

E extremamente importante que se utilize o construtor de referncias para arrays [ ] e porque $AoA[$i] = @temp; # Errado! est errado, pois a atribuiao de um array em contexto escalar devolve o seu nmero de a c u elementos, o que provavelmente no o que se pretende. a e Se estiver activado o pragma use strict; tero que ser acrescentadas algumas a declaraoes: c
use strict; my(@AoA, @temp); while (<>) { @temp = split; push @AoA, [ @temp ]; }

Claro que o array temporrio no necessita de existir... a a


while (<>) { push @AoA, [ split ]; }

Se se souber qual a posiao $i onde se quer colocar a referncia, usa-se: c e 67

my (@AoA, $i, $line); for $i ( 0 .. 10 ) { $line = <>; $AoA[$i] = [ split , $line ]; }

ou mesmo, apenas
my (@AoA, $i); for $i ( 0 .. 10 ) { $AoA[$i] = [ split , <> ]; }

Porm, no se deve abusar do uso de funoes que potencialmente podem devolver listas, e a c em contexto escalar, sem o indicar explicitamente. O seguinte cdigo seria mais claro: o
my (@AoA, $i); for $i ( 0 .. 10 ) { $AoA[$i] = [ split , scalar(<>) ]; }

Se se pretendesse utilizar uma referncia $ref_to_AoA, ter-se-ia que escrever algo como: e
while (<>) { push @$ref_to_AoA, [ split ]; }

J viu como pode adicionar linhas ao array de arrays. Mas como se adicionam colunas? a Se se est na presena de matrizes, simples utilizar a atribuiao directa: a c e c
for $x (1 .. 10) { for $y (1 .. 10) { $AoA[$x][$y] = func($x, $y); } } for $x ( 3, 7, 9 ) { $AoA[$x][20] += func2($x); }

No interessa se os elementos j existem ou no. O Perl cri-los- consoante necessrio, a a a a a a atribuindo aos elementos intermdios no utilizados undef. e a Se se pretender acrescentar elementos no m de uma linha, faz-se apenas # adiciona colunas a uma linha existente push @{ $AoA[0] }, "wilma", "betty"; Note que no se pode fazer a push $AoA[0], "wilma", "betty"; # ERRADO! pois este cdigo nem sequer compila. Porqu? Porque o argumento de push() tem de ser o e mesmo um array e no uma referncia para um array. a e 68

9.3

Acesso e impresso a

Imprimir apenas um dos elementos da estrutura trivial: e print $AoA[0][0]; Se se pretender imprimir toda a estrutura, no se pode fazer a print @AoA; # ERRADO! pois apenas se obtm uma lista com as referncias contidas no vector @AoA. Em vez disso, e e tem que se dereferir cada elemento sequencialmente para imprimir a estrutura completa:
for $aref ( @AoA ) { print "\t [ @$aref ],\n"; }

# os par^ntesis rectos s embelezam a impress~o e o a

Se se pretender imprimir os ndices, pode fazer-se:


for $i ( 0 .. $#AoA ) { print "\t elem $i is [ @{$AoA[$i]} ],\n"; }

ou mesmo (repare no ciclo interior em $j):


for $i ( 0 .. $#AoA ) { for $j ( 0 .. $#{$AoA[$i]} ) { print "\t elem $i $j is $AoA[$i][$j]\n"; } }

Isto est a complicar-se! E esta a razo porque, por vezes, mais simples utilizar variveis a a e a temporrias (uma referncia $aref, neste caso). a e
for $i ( 0 .. $#AoA ) { $aref = $AoA[$i]; for $j ( 0 .. $#{$aref} ) { print "\t elem $i $j is $AoA[$i][$j]\n"; } }

Hmm... ainda est feioso. E assim? a


for $i ( 0 .. $#AoA ) { $aref = $AoA[$i]; $n = @$aref - 1; for $j ( 0 .. $n ) { print "\t elem $i $j is $AoA[$i][$j]\n"; } }

69

9.4

Fatias

Se se pretende uma fatia (parte de uma linha) num array multidimensional tem de se recorrer a indexaao mais ou menos complicada. Isto porque no h um equivalente, para c a a fatias, ` dereferncia com apontadores que se aplica a elementos simples. (Lembre-se, a e claro, que pode sempre utilizar ciclos para obter as fatias.) Eis como retirar uma fatia com um ciclo:
@fatia = (); $x = 4; for ($y = 7; $y < 13; $y++) { push @fatia, $AoA[$x][$y]; }

O ciclo podia ser substitu por um fatiamento mais obscuro... do @fatia= @{ $AoA[4] } [ 7..12 ]; E se a fatia fr bidimensional como, por exemplo quando $x varia de 4 a 8 e $y varia de 7 o a 12? Eis uma forma simples...
@newAoA = (); for ($startx = $x = 4; $x <= 8; $x++) { for ($starty = $y = 7; $y <= 12; $y++) { $newAoA[$x - $startx][$y - $starty] = $AoA[$x][$y]; } }

Pode-se reduzir os ciclos com fatias...


for ($x = 4; $x <= 8; $x++) { push @newAoA, [ @{ $AoA[$x] } [ 7..12 ] ]; }

Se trabalhasse com Transformadas Schwartzianas, possivelmente utilizava map... @newAoA = map { [ @{ $AoA[$_] } [ 7..12 ] ] } 4 .. 8; mas, se o seu chefe o acusasse de segurar o emprego escrevendo cdigo ileg (s voc o o vel o e conseguia manter...), teria diculdade em defender-se. Se fosse a si, escrevia uma funao: c
@newAoA = splice_2D( \@AoA, 4 => 8, 7 => 12 ); sub splice_2D { my $lrr = shift; # l^ ref para array com refs para array! e my ($x_lo, $x_hi, $y_lo, $y_hi) = @_; # l^ os limites da indexaao e c~ return map { # e volta a usar map 8-) [ @{ $lrr->[$_] } [ $y_lo .. $y_hi ] ] } $x_lo .. $x_hi; }

70

9.5

Arrays de hashes, hashes de hashes, etc...

Exemplica-se brevemente alguns dos tpicos discutidos para os @AoA utilizando arrays de o hashes, hashes de hashes, etc. A principal diferena, neste caso, vai ser na forma de c aceder aos hashes: em vez de indexar com inteiros usa-se as funoes keys() e values(). c Vamos denir um array de hashes (array que contm referncias para hashes) e e explicitamente.
@AoH = ( # cria array de refer^ncias para hashes e { 1 => "fred", 2 => "barney" }, { 1 => "george", 2 => "jane", 3 => "elroy" }, { 1 => "homer", 2 => "marge", 3 => "bart" }, ); print $AoH[2]{1}, "\n"; # imprime homer

Eis vrias formas de imprimir os hashes apontados por cada referncia no array: a e
for $aref ( @temp print @temp print @temp print } @AoH ) { = %$aref; "\t [ @temp ],\n"; = keys %$aref; "\t [ @temp ],\n"; = values %$aref; "\t [ @temp ],\n"; # $aref refere sequencialmente cada hash # @temp um vector temporrio e a # imprime todo o hash (em pares chave-valor) # imprime s as chaves o # imprime s os valores o

Se se pretender explicitar os ndices faz-se:


for $i ( 0 .. $#AoH ) { print "\t hash $i [ @{[ %{$AoH[$i]} ]} ],\n"; e }

Bem complicado n? 8-) e Se se pretender imprimir elemento a elemento faz-se


for $i ( 0 .. $#AoH ) { for $j ( keys %{$AoH[$i]} ) { print "\t elem $i $j is $AoH[$i]{$j}\n"; } }

Esta foi mais leg vel. Pode criar-se um @AoH implicitamente quando se faz, por exemplo, $AoH[3]{b}=20; Para terminar mostra-se como constru um %HoH (hash of hashes), quer na forma e do directa, quer utilizando uma referncia, contendo os elementos (Simpsons) anteriormente e j referidos. a Note que na construao da referncia $ref_to_HoH os parntesis exteriores so chavetas c e e a (devolvem uma referncia para hash). e 71

$ref_to_HoH = { a => { 1 => "fred", 2 => "barney" }, b => { 1 => "george", 2 => "jane", 3 => "elroy" }, c => { 1 => "homer", 2 => "marge", 3 => "bart" }, }; %HoH = { a => { 1 => "fred", 2 => "barney" }, b => { 1 => "george", 2 => "jane", 3 => "elroy" }, c => { 1 => "homer", 2 => "marge", 3 => "bart" }, }; print $HoH{b}{2}, "\n"; # imprime jane print $ref_to_HoH->{c}{3}, "\n"; # imprime bart

Chega de estruturas de dados. Se quiser outras, vai ter de constru -las voc mesmo! e

72

10

Outras Funoes em Perl c

Apresenta-se uma lista parcial de funoes do Perl ordenadas segundo um critrio de c e aplicabilidade. Esta lista um subconjunto da lista que consta da secao perlfunc do e c manual. Note que algumas funoes se encontram repetidas. Note, tambm, que no se c e a discute, nem utiliza neste documento, algumas das funoes de uso mais raro ou mais c espec cas. Por exemplo, muitas delas esto intimamente ligadas ao ncleo do sistema a u operativo Unix/Linux, e esta introduao ao Perl no aborda esta matria. c a e Funces aplicveis a $ESCALAREs ou strings o a chomp, chop, chr, crypt, hex, index, lc, lcfirst, length, oct, ord, pack, q/STRING/, qq/STRING/, reverse, rindex, sprintf, substr, tr///, uc, ucfirst, y/// Expresses regulares e pesquisa de texto (pattern matching) o m//, pos, quotemeta, s///, split, study, tr// Funoes numricas c e abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand Funoes para @ARRAYs c pop, push, shift, splice, unshift Funoes para listas de dados c grep, join, map, qw/STRING/, reverse, sort, unpack Funoes para %HASHes c delete, each, exists, keys, values Funoes de entrada sa (input/output) c da binmode, close, closedir, dbmclose, dbmopen, die, eof, fileno, flock, format, getc, print, printf, read, readdir, rewinddir, seek, seekdir, select, syscall, sysread, sysseek, syswrite, tell, telldir, truncate, warn, write Funoes para dados de dimenso xa ou registos c a pack, read, syscall, sysread, syswrite, unpack, vec Funoes para lehandles, cheiros, ou directorias c -X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir, stat, symlink, umask, unlink, utime Termos relacionados com o controle da execuo dos programas ca caller, continue, die, do, dump, eval, exit, goto, last, next, redo, return, sub, wantarray Termos relacionados com o mbito (scope) das variveis a a caller, import, local, my, package, use Funoes vrias c a defined, dump, eval, formline, local, my, reset, scalar, undef, wantarray 73

Funoes para processos e grupos de processos c alarm, exec, fork, getpgrp, getppid, getpriority, kill, pipe, qx/STRING/, setpgrp, setpriority, sleep, system, times, wait, waitpid Termos relacionados com mdulos o do, import, no, package, require, use Termos relacionados com classes e orientao para objectos ca bless, dbmclose, dbmopen, package, ref, tie, tied, untie, use Funoes relacionadas com tempo c gmtime, localtime, time, times Da anterior lista, so aqui referidas mais algumas funoes ainda no discutidas. a c a dened VARIABLE Devolve verdadeiro se a varivel VARIABLE existe e falso em caso contrrio. Testa a a a existncia de escalares, arrays e hashes. e exists EXPR Dada uma expresso EXPR que especica um elemento de um array ou um elemento a de um hash, exists ser verdadeira se o elemento especicado j foi inicializado, a a mesmo que o seu valor actual seja indenido (undened). O elemento no a e auto-vivicado se no existir. a
print "Existe\n" print "Definido\n" print "Verdade\n" print "Existe\n" print "Definido\n" print "Verdade\n" if exists $hash{$key}; if defined $hash{$key}; if $hash{$key}; if exists $array[$index]; if defined $array[$index]; if $array[$index];

Um elemento de um hash ou de um array verdadeiro s se estiver denido, e e o e denido s se existir, mas o inverso no necessariamente verdade. o a e Pode aplicar-se exists a subrotinas. Devolve verdadeiro se a subrotina j foi a declarada, mesmo que esteja indenida. Mencionar o nome de uma subrotina no argumento de exists ou de defined no o mesmo que declar-la. a e a
print "Existe\n" print "Definida\n" if exists &subrotina; if defined &subrotina;

Finalmente, EXPR pode ser arbitrariamente complicada desde que a operaao nal c seja a leitura de um array ou de um hash, ou o nome de uma subrotina.
if if if if if (exists (exists (exists (exists (exists $ref->{A}->{B}->{$key}) $hash{A}{B}{$key}) $ref->{A}->{B}->[$ix]) $hash{A}{B}[$ix]) &{$ref->{A}{B}{$key}}) { { { { { } } } } }

74

Uma ultima nota: neste ultimo exemplo, o elemento de n mais profundo cuja vel existncia se testa no auto-vivicado, mas os elementos intermdios so-no. e a e e a Assim, $ref->{"A"} e $ref->{"A"}->{"B"} iro ser criados devido ao teste de a existncia do elemento $key. Isto acontece sempre que o operador seta utilizado. e e binmode FILEHANDLE Trata o cheiro referido por FILEHANDLE como um cheiro binrio. a bless REF, [CLASSNAME] Abenoa o item apontado pela referncia REF tornando-o num objecto da classe c e CLASSNAME (ou da classe impl cita na execuao). A orientaao por objectos em Perl c c obscura 8-). Consulte os manuais relativos a OO em Perl. e getc FILEHANDLE Devolve o prximo byte cont o guo no cheiro apontado por FILEHANDLE. No m do cheiro devolve a string nula (que d falso em contexto lgico). a o gmtime EXPR Converte um tempo dado pela funao time para uma data. c goto [LABEL|EXPR|&NAME] sleep EXPR Esta funao adormece o script por EXPR segundos e devolve o nmero de segundos c u efectivamente passados, pois pode ser interrompida com um alarme. Como a unidade de contagem de tempo o segundo, no sucientemente precisa para e a e certas tarefas de temporizaao. c pack TEMPLATE, LISTA Empacota a LISTA numa estrutura binria, segundo a sequncia de caracteres a e denida em TEMPLATE, e devolve a string contendo a estrutura. unpack TEMPLATE, EXPR Faz a operaao inversa de pack. Desempacota, para uma lista, a string especicada c por EXPR na forma especicada por TEMPLATE e devolve-a.

75

11

Concluso a

Esta foi uma breve (?) introduao ao Perl. No futuro ser expandida. Talvez seja c a convertida para html... Who knows? 8-). Ficaram muitos assuntos por abordar. No se esquea que a actual ediao (a terceira) do a c c livro Programming Perl, de Larry Wall et al., OReilly & Associates, tem cerca de 1100 pginas! Obviamente muitos aspectos do Perl tiveram que ser omitidos. a Finalmente, no se esquea que a informaao actualizada para a verso do Perl que a c c a utiliza est nas pginas de manual que normalmente so instaladas com o interpretador. a a a Consulte-as!

76

Você também pode gostar