Perl - Referências

Uma referência Perl é um tipo de dados escalar que contém a localização de outro valor que pode ser escalar, matrizes ou hashes. Por causa de sua natureza escalar, uma referência pode ser usada em qualquer lugar, um escalar pode ser usado.

Você pode construir listas contendo referências a outras listas, que podem conter referências a hashes e assim por diante. É assim que as estruturas de dados aninhadas são construídas em Perl.

Criar Referências

É fácil criar uma referência para qualquer variável, sub-rotina ou valor prefixando-o com uma barra invertida da seguinte maneira -

$scalarref = \$foo;
$arrayref  = \@ARGV;
$hashref   = \%ENV;
$coderef   = \&handler;
$globref   = \*foo;

Você não pode criar uma referência em um identificador de I / O (filehandle ou dirhandle) usando o operador de barra invertida, mas uma referência a uma matriz anônima pode ser criada usando os colchetes da seguinte maneira -

$arrayref = [1, 2, ['a', 'b', 'c']];

De maneira semelhante, você pode criar uma referência a um hash anônimo usando as chaves da seguinte maneira -

$hashref = {
   'Adam'  => 'Eve',
   'Clyde' => 'Bonnie',
};

Uma referência a uma sub-rotina anônima pode ser criada usando sub sem um subnome como segue -

$coderef = sub { print "Boink!\n" };

Desreferenciamento

A desreferenciação retorna o valor de um ponto de referência para o local. Para cancelar a referência de uma referência, simplesmente use $, @ ou% como prefixo da variável de referência, dependendo se a referência está apontando para um escalar, array ou hash. A seguir está o exemplo para explicar o conceito -

#!/usr/bin/perl

$var = 10;

# Now $r has reference to $var scalar.
$r = \$var;

# Print value available at the location stored in $r.
print "Value of $var is : ", $$r, "\n";

@var = (1, 2, 3);
# Now $r has reference to @var array.
$r = \@var;
# Print values available at the location stored in $r.
print "Value of @var is : ",  @$r, "\n";

%var = ('key1' => 10, 'key2' => 20);
# Now $r has reference to %var hash.
$r = \%var;
# Print values available at the location stored in $r.
print "Value of %var is : ", %$r, "\n";

Quando o programa acima é executado, ele produz o seguinte resultado -

Value of 10 is : 10
Value of 1 2 3 is : 123
Value of %var is : key220key110

Se você não tiver certeza sobre um tipo de variável, é fácil saber seu tipo usando ref, que retorna uma das seguintes strings se seu argumento for uma referência. Caso contrário, retorna falso -

SCALAR
ARRAY
HASH
CODE
GLOB
REF

Vamos tentar o seguinte exemplo -

#!/usr/bin/perl

$var = 10;
$r = \$var;
print "Reference type in r : ", ref($r), "\n";

@var = (1, 2, 3);
$r = \@var;
print "Reference type in r : ", ref($r), "\n";

%var = ('key1' => 10, 'key2' => 20);
$r = \%var;
print "Reference type in r : ", ref($r), "\n";

Quando o programa acima é executado, ele produz o seguinte resultado -

Reference type in r : SCALAR
Reference type in r : ARRAY
Reference type in r : HASH

Referências circulares

Uma referência circular ocorre quando duas referências contêm uma referência uma à outra. Você deve ter cuidado ao criar referências, caso contrário, uma referência circular pode levar a vazamentos de memória. A seguir está um exemplo -

#!/usr/bin/perl

 my $foo = 100;
 $foo = \$foo;
 
 print "Value of foo is : ", $$foo, "\n";

Quando o programa acima é executado, ele produz o seguinte resultado -

Value of foo is : REF(0x9aae38)

Referências a funções

Isso pode acontecer se você precisar criar um manipulador de sinal para que possa produzir uma referência a uma função precedendo esse nome de função com \ & e para desreferenciar essa referência, você simplesmente precisa prefixar a variável de referência usando "e" comercial &. A seguir está um exemplo -

#!/usr/bin/perl

# Function definition
sub PrintHash {
   my (%hash) = @_;
   
   foreach $item (%hash) {
      print "Item : $item\n";
   }
}
%hash = ('name' => 'Tom', 'age' => 19);

# Create a reference to above function.
$cref = \&PrintHash;

# Function call using reference.
&$cref(%hash);

Quando o programa acima é executado, ele produz o seguinte resultado -

Item : name
Item : Tom
Item : age
Item : 19