var_dump em Perl

novembro 12, 2008 by

Nos primeiros dias de Perl eu já precisei de algo parecido com var_dump do PHP, até pela falta de um debug mais adequado.

No Perl o módulo correspondente é o Data::Dumper:
use Data::Dumper;
 
my $scalar = 'Teste';
print Dumper($scalar);
 
my %hash = ( nome => 'Jane' );
print Dumper(\%hash);
 
my @array = ( 'Jane', 'Doe' );
print Dumper(\@array);
 
my $hashref = { idade => 27 };
print Dumper($hashref);
 
my $arrayref = [ 'um', 'dois', 3 ];
print Dumper($arrayref);
 

Um detalhe importante é que a função Dumper retorna a estrutura como string, então para ver os dados é preciso dar print.

Observe ainda que as variáveis @array e %hash foram passadas por referência, com uma barra invertida antes do nome.

Se não fosse feita a referência, o conteúdo de cada uma seria expandido. Ao invés de uma lista com os nomes Jane e Doe, o Dumper exibiria as strings separadamente, como se ele tivesse sido chamado como Dumper('Jane', 'Joe'). A mesma coisa para o hash; sem a referência seria como Dumper('nome', 'Jane').

Esse assunto de referenciar e de-referenciar vale a pena deixar para um post futuro.

Teste aí e veja no que dá 😉

Manual básico e em português de Perl

novembro 11, 2008 by

Pessoal, encontrei um site simples, que tem um material bom, básico para quem está iniciando.

Ele está todo em português, acho que ajuda muito para o primeiro contato com o Perl.

http://paginas.terra.com.br/informatica/silvello/perl/

Monges do Perl

novembro 11, 2008 by

Perl Monks é uma comunidade que visa a interatividade e compartilhamento de conhecimento entre programadores Perl, iniciantes e avançados. É uma achado, e já me cadastrei.

Junte-se ao monastério e siga a trilha que nos levará em direção à iluminação junto com os maiores monges da programação!

www.perlmonks.org

Writing serious Perl

novembro 10, 2008 by

Esse tutorial é fundamental. É um dos mais cotados no del.icio.us. Já imprimi e estou testando as dicas.
Explica a melhor maneira de trabalhar com Packages e orientação a objetos. Conhecimento básico em Perl é necessário para um entendimento total.

http://www.netalive.org/tinkering/serious-perl/

O primeiro script em Perl

novembro 10, 2008 by

No post sobre instalação do modperl, foi utilizado o seguinte script de teste:

use strict;
use warnings;
 
my $r = shift;
 
$r->content_type("text/html");
 
print "Funcionou!";

Pra quem está chegando no Perl agora, já dá pra perceber algumas bizarrices curiosidades.

use strict; use warnings;

Estas duas linhas são consideradas boa prática em qualquer script que servirá pra algo mais que um teste rápido.

strict e warnings são pragmas do Perl; são módulos que alteram o compartamento interno do interpretador.

O pragma strict restringe o uso de algumas declarações que poderiam levar o programador a enganos, como a utilização de variáveis sem escopo declarado. Havendo algum problema, o interpretador não prossegue e o script não é iniciado.

Já o pragma warnings avisa sobre comportamentos não tratados, como ao somar uma string não numérica com um inteiro. No modperl, estes avisos serão mostrados no log de erro do Apache.

Para um código minimamente claro e de depuração um pouco mais fácil, o uso destas duas declarações em cada script é fundamental.

Escopo

Para seguir o uso strict, cada variável precisa ter seu escopo definido.

No teste, a variável $r foi precedida de my para declarar o seu escopo – neste caso é o escopo do arquivo.

Quando a declaração é feita dentro de algum bloco (closure), o tempo de vida da variável fica limitado ao bloco ao qual pertence.

my $idade = 22;
if ( $idade > 18 ) {
    my $mensagem = "Você que tem $idade anos!";
    print $mensagem;
}
# aqui fora, a variável $mensagem não existe mais!

Scalar, Array e Hash

No Perl você vai se deparar com estes três tipos de variável:

my $scalar = “Inteiro ou string”;

my @lista = (‘lista’, ‘de’, ‘qualquer’, ‘coisa’);

my %dicionario = (
    ‘pais’ => ‘Brasil’,
    ‘estado’ => ‘Rio de Janeiro’,
    ‘cidade’ => ‘Rio de Janeiro’,
);

No PHP, o array ser de índice numérico, como uma lista mesmo, ou associativo, funcionando como um dicionário.

No Perl (e na maioria das linguagens), o array é apenas para fins de lista, enquanto o dicionário é representado por um hash.

O importante é lembrar que a declaração é feita com $ para scalar, @ para lista e % para hash.

Ao acessar um array ou hash, o $ é utilizado:

print $lista[2];
# mostra a palavra qualquer
 
print $dicionario{'pais'};
# mostra Brasil

A variável $_

Em muitos casos, algumas funções dispensam argumentos e trabalham diretamente com variáveis pré-definidas. Por exemplo:

open(ARQUIVO, "/etc/crontab");
while (<ARQUIVO>) {
    print;
}
close(<ARQUIVO>);

O loop na verdade utiliza a variável $_ implicitamente. O trecho acima seria o mesmo que:

while ($_ = <ARQUIVO>) {
    print $_;
}

De uma forma geral, é conveniente evitar o seu uso a favor de um código mais claro:

while (my $linha = <ARQUIVO>) {
    print $linha;
}

Observe o uso do my para declarar a variável no escopo do while. Fora dele ela deixará de existir.

Funções

As funções são declaradas com sub (de subrotina) e não têm assinatura dos parâmetros. Ao invés disso, os argumentos chegam no array @_.

Quando a função espera somente um argumento, eu costumo ver o uso da função shift para recuperá-lo:

sub diga_oi {
    my $nome = shift;
    print "Oi $nome";
}
 
diga_oi("Nash");

Assim como algumas funções utilizam $_ no contexto de scalar, a função shift utiliza o @_ no contexto de array quando está dentro de funções, retirando e retornando o primeiro elemento.

Se a função espera mais de um argumento, ao invés de utilizar o shift várias vezes é comum associar cada item da lista a uma variável:

sub nova_mensagem {
    my ($usuario, $mensagem) = @_;
    print "$usuario disse: $mensagem";
}
 
nova_mensagem("Bart", "Eu não fiz isso!");

Se você passar argumentos a mais, eles serão ignorados. Se faltar algum, as respectivas variáveis ficarão como undef sem que nenhum erro ocorra.

O request no modperl

Quando o modperl foi configurado, utilizamos PerlHandler ModPerl::Registry.

Este handler pega o script Perl acessado pelo Apache e o executa como se fosse uma função.

Considerando que agora o script é uma função, fazer my $r = shift; nada mais é do que pegar o primeiro argumento passado pelo array @_, que neste caso é um objeto Apache2::RequestRec.

Este objeto representa a ligação direta entre o modperl e o Apache, permitindo acessar e alterar diversos elementos da requisição e resposta.

No teste feito foi necessário definir o tipo do conteúdo da resposta para Html pelo método content_type (coisa que o PHP faz automaticamente, até por causa da proposta de cada linguagem).

Sabe tudo de Perl agora!

Acho que agora deu pra desmistificar um pouco o primeiro script web.

Ou não?

Perl para entendedores de PHP

novembro 7, 2008 by

Caminhando e cantando pela web, no meu inicio de aprendizado, descobrir uma ótima página que faz comparações entre PHP e Perl no sentido de Sintaxe. Eu como um humilde desenvolvedor PHP fiquei maravilhado por conseguir realmente entender o que o Perl queria me dizer com algumas sintaxes.

Bem, chega de enrrolação, segue abaixo as traduções Perl-PHP:

— Perl arrays — Php arrays
@a = ();

@a = ( 'xx', 11, 33.5, );

@a = 12..33;

$a[2] = 'something';

$len = scalar(@a);
# or
$len = @a;

@a3 = ('xx', @a1, @a2);

($x, $y) = @a;

$a[@a] = 'new'; # push

push
pop
shift
unshift
splice

foreach $i (@a) { .. }
$a = array();

$a = array( 'xx', 11, 33.5, );

$a = range(12,33);

$a[2] = 'something';

$len = count($a);

$a3 = array_merge('xx', $a1, $a2);

list($x, $y) = $a;

$a[] = 'new'; # push

array_push
array_pop
array_shift
array_unshift
array_splice

foreach ($a as $i) { .. }

— Perl hashes — Php hashes
%h = ();

%h = ( 'x' => 'y',
       'z' => 'w',
     );

$h{'x'} = 7;

while (($key,$value) = each(%h))
{ .. }

$a = keys(%h);
$b = values(%h);

delete $h{'x'};
$h = array();

$h = array( 'x' => 'y',
            'z' => 'w',
          );

$h['x'] = 7;

foreach ($h as $key => $value)
{ .. }

$a = array_keys($h);
$b = array_values($h);

unset( $h['x'] );

— Perl data structures — Php data structures
%h = ('a'=>13, 'b'=>25);
@x = ('hi', 'there', 'all',);

@mix = ( \%h, \@x,
         [33..39],
	 { x=>15, yy=>23, },
       );

$mix[0]->{'b'}  # == 25
$mix[0]{'b'}    # == 25
$mix[2]->[2]    # == 35
$mix[2][2]      # == 35
$h = array('a'=>13, 'b'=>25);
$x = array('hi', 'there', 'all',);

$mix = array($h, $x,
	     range(33,39),
	     array('x'=>15, 'yy'=>23),
	    );

$mix[0]['b']  # == 25

$mix[2][2]    # == 35

— Perl array split/join — Php array split/join
@a = split( '\|', $s );

@a = split( '\s+', $s );

$s = join( '|', @a );
$a = preg_split( '/\|/', $s,
            -1, PREG_SPLIT_NO_EMPTY );
$a = preg_split( '/\s+/', $s,
            -1, PREG_SPLIT_NO_EMPTY );

$s = join( '|', $a );

— Perl case conversion — Php case conversion
$s = lc($s);
$s = uc($s);

$s =~ tr/a-z/A-Z/;
$s = strtolower($s);
$s = strtoupper($s);

— Perl string comparisons — Php string comparisons
$s1 eq $s2

$s1 lt $s2
strcmp($s1,$s2) == 0
# or
$s1 === $s2

strcmp($s1,$s2) < 0

— Perl functions — Php functions
sub foo {
 my @args = @_;
}

sub foo {
 $x = 5;
}

foo2( \@a, \%h );
function foo() {
 $args = func_get_args();
}

function foo() {
 global $x;
 $x = 5;
}

function foo2($x, $y) {
}

foo2( $a, $h );

— Perl string matching operations — Php string matching operations
$s =~ m/(\w+)/;
$substr = $1;

@all = ($s =~ m/(\w+)/g);

$s =~ s/\s+/X/;
$s =~ s/\s+/X/g;

$s =~ s/^\s+|\s+$//g;
preg_match( "/(\w+)/", $s, $match );
$substr = $match[1];

preg_match_all( "/(\w+)/", $s, $match );
$all = $match[0];

$s = preg_replace( "/\s+/", 'X', $s, 1 );
$s = preg_replace( "/\s+/", 'X', $s );

$s = trim($s);

— Perl basename/dirname — Php basename/dirname
use File::Basename;

$b = basename($path);
$d = dirname($path);
$b = basename($path);
$d = dirname($path);

— Perl environment variables — Php environment variables
%ENV

$ENV{REQUEST_METHOD}

$ARGV[$i]

$0
$_SERVER

$_SERVER[REQUEST_METHOD]

$argv[$i+1]

$argv[0]  # Php/CGI only

— Perl POST/GET parameters — Php POST/GET parameters
#form/hyperlink parameters:
# s : single-valued
# m : multi-valued

use CGI (:standard);

$s = param('s');
@m = param('m');

@param_names = param();
$num_params = param();
#form/hyperlink parameters:
# s   : single-valued
# m[] : multi-valued
#       (such as multi-selections
#        and checkbox groups)

$PARAM
  = array_merge($_GET, $_POST);

$s = $PARAM['s'];  # a scalar
$m = $PARAM['m'];  # an array

$param_names = array_keys($PARAM);
$num_params = count($PARAM);

— Perl HTML elements — Php HTML elements
use CGI (:standard);

$ref = "x.cgi";
a({href=>$ref}, "yy")

textfield({name=>"yy", size=>5})

password({name=>"yy", size=>5})

textarea({name=>"yy",
	  cols=>5, rows=>2})

submit({value=>"yy"})

button( {name=>"xx",
	 value=>"yy",
         onclick=>"submit()",
        }
      )

%labels = (0=>'a',1=>'q',2=>'x');
popup_menu( { name=>"xx",
              values=>[0..2],
              labels=>\%labels,
              size=>4,
	    }
          )

@a = ('xx','yy','zz');
radio_group( { name=>'nn',
               values=> \@a,
               default=>'_',
               linebreak=>1,
	     }
           )

%labels = ('xx'=>'L1','yy'=>'L2');
@a = keys( %labels );
checkbox_group( { name=>'nn',
                  values=> \@a,
		  labels=> \%labels,
	        }
              )

table(
       Tr(
           [
	     td(['a','b']),
             td(['x','y']),
	   ]
         )
     )
# The Perl/CGI functions have the
# additional property of "stability"
# when used in reentrant forms.
# The values of the HTML elements are
# set according to the incoming
# parameter values for those elements.
# The versions below are not stable.

$ref = "x.php";
<a href="<?php echo $ref?>">yy</a>

<input type=text name=yy size=5>

<input type=password name=yy size=5>

<textarea name=yy cols=5 rows=2>
</textarea>

<input type="submit" value=yy>

<input type="button"
  name="xx" value="yy"
  onclick="submit()">

<select name="xx" size="4">
<?php
$labels = array(0=>'a',1=>'q',2=>'x');
foreach (range(0,2) as $_)
  echo "<option value='$_'>",
       $labels[$_];
?>
</select>

$a = array('xx','yy','zz');
foreach ($a as $_)
  echo "<input type=radio
         name=nn value='$_'>$_<br>";

$labels = array('xx'=>'L1','yy'=>'L2');
foreach (array_keys($labels) as $_)
  echo "<input type=checkbox
         name=nn value='$_'>",
         $labels[$_];

<table>
<tr>
<td>a</td><td>b</td>
</tr>
<tr>
<td>x</td><td>y</td>
</tr>
</table>

— Perl URL encode — Php URL encode
use URI::Escape;

uri_escape($val)
uri_unescape($val)
urlencode($val)
urldecode($val)

— Perl MySQL — Php MySQL
use DBI;
$dbh = DBI->connect(
  'DBI:mysql:test:localhost',
  $usr,$pwd
);

$dbh->do( $sql_op )

$query = $dbh->prepare( $sql_op );
$query->execute();

while(
 @record = $query->fetchrow() )
{ .. }

$dbh->quote($val)
$dbh = mysql_connect(
  'localhost', $usr, $pwd
);
mysql_query('USE test')

mysql_query( $sql_op );

$results = mysql_query( $sql_op );

while($record =
        mysql_fetch_row($results))
{ .. }

"'" . addslashes($val) . "'"

Tendo conhecimento em PHP, este “guia” acima dá um esclarescimento para entender alguns códigos em Perl.

Caminho longo…, e viva o PHP! \o/

Rafael S.

Referência: http://www.cs.wcupa.edu/~rkline/perl2php/

Instalando modperl no Apache no Linux

novembro 7, 2008 by

É muito mais fácil começar a aprender Perl com scripts por linha de comando. Mas isso seria chato. Eu pelo menos não tinha muita coisa pra fazer. Então vamos direto a aplicações web.

Os scripts podem ser executados como CGI, assim como PHP ou Python, mas, também como estas duas linguagens, o Perl dispõe de um mod para o Apache que torna a execução muito mais rápida já que o interpretador não precisa ser carregado a cada execução. Outros benefícios ficarão claros mais pra frente, mas por enquanto nada de detalhes.

O Perl certamente já está instalado no seu Linux. Considero ainda que o Apache 2 também esteja e que você está utilizando Debian ou Ubuntu.

Para instalar o pacote do modperl:

# aptitude install libapache2-mod-perl2

Algumas poucas dependências serão instaladas e pronto.

Como parte da instalaçao, foi criado o arquivo /etc/apache2/mods-available/perl.load com o conteúdo:

LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so

Aqui no Debian, a instalação já habilitou o módulo fazendo um link simbólico para /etc/apache2/mods-enabled/perl.load. Caso isso não tenha ocorrido, habilite-o com o seguinte comando:

# a2enmod perl

Os arquivos do diretório mods-enabled são interpretados pelo Apache durante a inicialização, que então carregará o módulo instalado.

Agora é necessário configurar quais arquivos o modperl interpretará. Para isso, configure o seguinte:

<Files “*.pl”>
    SetHandler perl-script
    PerlHandler ModPerl::Registry
    Options +ExecCGI
</Files>

Esta configuração pode ser realizada no escopo global do arquivo de configuração, em algum VirtualHost, Directory ou arquivo .htaccess. Aqui eu preferi manter no VirtualHost padrão no arquivo /etc/apache2/sites-enabled/000default. Dessa forma, todos os scripts com extensão .pl serão executados pelo handler ModPerl::Registry, que um dia talvez a gente descubra como funciona 😛

Para testar, crie este arquivo com extensão .pl e acesse:

use strict;
use warnings;
 
my $r = shift;
 
$r->content_type(“text/html”);
 
print “Funcionou!”;

O script a gente vê depois 🙂

E então? Funcionou? Não? Falei alguma besteira? Tem alguma sugestão?

Hello world!

novembro 6, 2008 by

Se você, jovem, que completou 18 anos e chegou até aqui mas não sabe do se trata, explico.

O blog é uma iniciativa de um grupo de programadores (apesar dos demais ainda não concordarem com a idéia) com objetivo de estudar e começar a programar Perl. Não que seja uma coisa bacana do tipo que reúne os amigos no final de semana, mas acho que pode nos ajudar.

Certamente existem outras fontes para aprender Perl pra quem não é do grupo; essa é só a nossa experiência. Ou pelo menos a nossa experiência até o blog morrer.

Até mais!

Ps: vida longa ao PHP \o/