La mejor manera de pasar hashes y matrices es por reference. Una referencia es simplemente una forma de hablar sobre una estructura de datos compleja como un único punto de datos, algo que se puede almacenar en una variable escalar (como $foo
).
Lea en references, por lo que entiende cómo crear una referencia desreferencia una referencia para recuperar sus datos originales.
Lo básico: usted antepone su estructura de datos con una barra diagonal inversa para obtener la referencia a esa estructura.
my $hash_ref = \%hash;
my $array_ref = \@array;
my $scalar_ref = \$scalar; #Legal, but doesn't do much for you...
Una referencia es una ubicación de memoria de la estructura original (además de una pista acerca de la estructura):
print "$hash_ref\n";
imprimirá algo como:
HASH(0x7f9b0a843708)
Para obtener la referencia de vuelta en un formato utilizable, simplemente ponga la referencia en el sigil correcto al frente:
my %new_hash = %{ $hash_ref };
Debe aprender a usar referencias ya que esta es la forma en que puede crear estructuras de datos extremadamente complejas en Perl, y cómo funciona Perl orientado a objetos.
Digamos que quiere pasar tres hashes a su subrutina.Estos son los tres valores hash:
my %hash1 = (this => 1, that => 2, the => 3, other => 4);
my %hash2 = (tom => 10, dick => 20, harry => 30);
my %hash3 = (no => 100, man => 200, is => 300, an => 400, island => 500);
voy a crear las referencias para ellos
my $hash_ref1 = \%hash1;
my $hash_ref2 = \%hash2;
my $hash_ref3 = \%hash3;
Y ahora sólo tiene que pasar las referencias:
mysub ($hash_ref1, $hash_ref2, $hash_ref3);
Las referencias son escalares de datos, así que no hay problema para pasarlos a mi subrutina:
sub mysub {
my $sub_hash_ref1 = shift;
my $sub_hash_ref2 = shift;
my $sub_hash_ref3 = shift;
Ahora, simplemente me desreferencia, y mi subrutina puede usarlos.
my %sub_hash1 = %{ $sub_hash_ref1 };
my %sub_hash2 = %{ $sub_hash_ref2 };
my %sub_hash3 = %{ $sub_hash_ref3 };
Se puede ver lo que una referencia es una referencia a utilizando el comando ref:
my $ref_type = ref $sub_hash_ref; # $ref_type is now equal to "HASH"
Esto es útil si desea asegurarse de que está siendo pasado el tipo correcto de la estructura de datos .
sub mysub {
my $hash_ref = shift;
if (ref $hash_ref ne "HASH") {
croak qq(You need to pass in a hash reference);
}
También tenga en cuenta que estas son las referencias a memoria, por lo que la modificación de la referencia modificará el hash original:
my %hash = (this => 1, is => 2, a => 3 test => 4);
print "$hash{test}\n"; # Printing "4" as expected
sub mysub (\%hash); # Passing the reference
print "$hash{test}\n"; # This is printing "foo". See subroutine:
sub mysub {
my $hash_ref = shift;
$hash_ref->{test} = "foo"; This is modifying the original hash!
}
Esto puede ser bueno - que le permite modificar los datos pasados a la subrutina, o malo - le permite involuntariamente modificar los datos pasados a la subrutina original.
+1: para 'mi% hash =% {$ _ [0]};' –