segunda-feira, 18 de agosto de 2008

Passagem de array como parâmetro em subrotinas de Perl

Passar um array como parâmetro em uma subrotina de Perl pode ser muito complicado sem saber todos os conceitos da linguagem. Veja abaixo um exemplo de uma função recebendo arrays de cinco maneiras diferentes:
sub faz_nada_util
{
print "(" . $_[0] . "," . $_[1] . ")";
}

my @array_1 = (1,2);
my @array_2 = [3,4];

faz_nada_util @array_1;
faz_nada_util \@array_1;
faz_nada_util @array_2;
faz_nada_util (5,6);
faz_nada_util [7,8];

A saída será:
(1,2)
(ARRAY(0x81536b4),)
(ARRAY(0x815360c),)
(5,6)
(ARRAY(0x8176f5c),)

O importante no exemplo é verificar que quando criamos um array utilizando colchetes [] estamos retornando na verdade não o array, mas a referência a este array. Dessa forma o primeiro item de @_ seria a referência ao array. Isso é mostrado na terceira e na última linha do resultado.

Quando criamos com o uso de parênteses () temos na váriavel o array em si. Então quando passamos esta lista à subrotina, os itens são copiados um a um no array @_. Isso é demonstrado na primeira e na quarta linha do resultado. Usando a contra-barra \ indicamos no segundo print que queremos enviar a referência do array criado com parênteses.

Mas e se você fizer uma função que receba como parâmetro um texto e um array como parâmetros? Você pode fazer da seguinte maneira:
sub continua_fazendo_nada_util
{
my $nome = shift;
print $nome . ": \n";
foreach $nome ( @_ ) {
print "- " . $nome . "\n";
}
}
continua_fazendo_nada_util("tiago", (1,2,3,4));

É como se a função recebesse como parâmetro um único grande array. Esse tipo de solução funciona bem quando o último parâmetro é o array, pois podemos dar shift dos parâmetros iniciais e iterar com os restantes. Num caso por exemplo em que a função deva receber dois arrays, podemos fazer a passagem de parâmetro pela referência.
sub nada_pra_fazer_aqui
{
my @array_1 = @{$_[0]};
my @array_2 = @{$_[1]};

print "array1: \n";
foreach $a (@array_1) {
print "- $a\n";
}
print "array2: \n";
foreach $a (@array_2) {
print "- $a\n";
}

}
nada_pra_fazer_aqui [1,2,3], [4,5,6];

Um comentário: