¿Cuál es la diferencia entre un hash y una referencia hash en Perl?
-
08-07-2019 - |
Pregunta
Me gustaría entender correctamente los hashes en Perl. He tenido que usar Perl de forma intermitente durante bastante tiempo y, sobre todo, cada vez que necesito hacerlo, está relacionado principalmente con el procesamiento de texto.
Y cada vez que tengo que lidiar con hashes, se estropea. La sintaxis me parece muy críptica para los hash
Una buena explicación de los hash y las referencias de hash, sus diferencias, cuándo se requieren, etc. sería muy apreciada.
Solución
Un hash simple está cerca de una matriz. Sus inicializaciones incluso se parecen. Primero la matriz:
@last_name = (
"Ward", "Cleaver",
"Fred", "Flintstone",
"Archie", "Bunker"
);
Ahora representemos la misma información con un hash (también conocido como matriz asociativa):
%last_name = (
"Ward", "Cleaver",
"Fred", "Flintstone",
"Archie", "Bunker"
);
Aunque tienen el mismo nombre, la matriz @last_name
y el hash % last_name
son completamente independientes.
Con la matriz, si queremos saber el apellido de Archie, tenemos que realizar una búsqueda lineal:
my $lname;
for (my $i = 0; $i < @last_name; $i += 2) {
$lname = $last_name[$i+1] if $last_name[$i] eq "Archie";
}
print "Archie $lname\n";
Con el hash, es mucho más directo sintácticamente:
print "Archie $last_name{Archie}\n";
Digamos que queremos representar información con una estructura ligeramente más rica:
- Cuchilla (apellido)
- Ward (primer nombre)
- junio (nombre del cónyuge)
- Picapiedra
- Fred
- Wilma
- búnker
- Archie
- Edith
Antes de que aparecieran las referencias, los hashes planos de valores clave eran lo mejor que podíamos hacer, pero las referencias lo permiten
my %personal_info = (
"Cleaver", {
"FIRST", "Ward",
"SPOUSE", "June",
},
"Flintstone", {
"FIRST", "Fred",
"SPOUSE", "Wilma",
},
"Bunker", {
"FIRST", "Archie",
"SPOUSE", "Edith",
},
);
Internamente, las claves y los valores de % personal_info
son todos escalares, pero los valores son un tipo especial de escalar: referencias hash, creadas con {}
. Las referencias nos permiten simular " multidimensional " hashes Por ejemplo, podemos llegar a Wilma a través de
$personal_info{Flintstone}->{SPOUSE}
Tenga en cuenta que Perl nos permite omitir flechas entre subíndices, por lo que lo anterior es equivalente a
$personal_info{Flintstone}{SPOUSE}
Es mucho escribir si quieres saber más sobre Fred, por lo que puedes tomar una referencia como una especie de cursor:
$fred = $personal_info{Flintstone};
print "Fred's wife is $fred->{SPOUSE}\n";
Debido a que $ fred
en el fragmento de arriba es un hashref, la flecha es necesaria. Si lo omite pero habilitó sabiamente use estricto
para ayudarlo a detectar este tipo de errores, el compilador se quejará:
Global symbol "%fred" requires explicit package name at ...
Las referencias de Perl son similares a los punteros en C y C ++, pero nunca pueden ser nulos. Los punteros en C y C ++ requieren desreferenciación y también las referencias en Perl.
Los parámetros de la funciónC y C ++ tienen una semántica de paso por valor: son solo copias, por lo que las modificaciones no vuelven a la persona que llama. Si desea ver los cambios, debe pasar un puntero. Puede obtener este efecto con referencias en Perl:
sub add_barney {
my($personal_info) = @_;
$personal_info->{Rubble} = {
FIRST => "Barney",
SPOUSE => "Betty",
};
}
add_barney \%personal_info;
Sin la barra diagonal inversa, add_barney
habría obtenido una copia que se desecha tan pronto como regrese el sub.
Tenga en cuenta también el uso de la "coma gruesa" ( = >
) arriba. Cita automáticamente la cadena a su izquierda y hace que las inicializaciones de hash sean menos sintácticamente ruidosas.
Otros consejos
A continuación se muestra cómo puede usar un hash y una referencia de hash:
my %hash = (
toy => 'aeroplane',
colour => 'blue',
);
print "I have an ", $hash{toy}, " which is coloured ", $hash{colour}, "\n";
my $hashref = \%hash;
print "I have an ", $hashref->{toy}, " which is coloured ", $hashref->{colour}, "\n";
Consulte también perldoc perldsc .
Un hash es un tipo de datos básico en Perl. Utiliza claves para acceder a su contenido.
Una referencia hash es la abreviatura de un referencia a un hash. Las referencias son escalares, eso es valores simples. Es un valor escalar que contiene esencialmente, un puntero a lo real hash en sí.
Enlace: diferencia entre hash y hash ref en perl - Foros de Ubuntu
Una diferencia también está en la sintaxis para eliminar. Al igual que C, Perl funciona así para Hashes:
delete $hash{$key};
y para referencias de hash
delete $hash_ref->{$key};
El Perl Hash Howto es un gran recurso para entender Hashes versus Hash con referencias de Hash
También hay otro enlace aquí que tiene más información sobre perl y referencias .
Consulte perldoc perlreftut , que también se puede acceder en la línea de comandos de su computadora.
Una referencia es un valor escalar que se refiere a una matriz completa o un hash completo (o casi cualquier otra cosa). Los nombres son un tipo de referencia con el que ya estás familiarizado. Piense en el presidente de los Estados Unidos: una bolsa de sangre y huesos desordenada e inconveniente. Pero para hablar de él, o para representarlo en un programa de computadora, todo lo que necesita es la cadena escalar fácil y conveniente "Barack Obama".
Las referencias en Perl son como nombres para matrices y hashes. Son los nombres privados e internos de Perl, por lo que puede estar seguro de que no son ambiguos. A diferencia de "Barack Obama", una referencia solo se refiere a una cosa, y siempre se sabe a qué se refiere. Si tiene una referencia a una matriz, puede recuperar toda la matriz de ella. Si tiene una referencia a un hash, puede recuperar el hash completo. Pero la referencia sigue siendo un valor escalar fácil y compacto.