¿Cuál es la diferencia entre una referencia hash y hash en Perl?

Me gustaría entender correctamente hashes en Perl. He tenido que usar Perl intermitentemente durante bastante tiempo y, sobre todo cuando tengo que hacerlo, está relacionado principalmente con el procesamiento de texto.

Y cada vez que tengo que lidiar con hashes, se arruina. Encuentro la syntax muy críptica para hashes

Una buena explicación de hashes y referencias hash, sus diferencias, cuando sean requeridas, etc. sería muy apreciada.

Un hash simple está cerca de una matriz. Sus inicializaciones incluso se ven similares. 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 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 solo un poco más rica:

  • Cleaver (apellido)
    • Ward (primer nombre)
    • Junio ​​(nombre de stack del cónyuge)
  • Picapiedras
    • Fred
    • Wilma
  • Búnker
    • Archie
    • Edith

Antes de que llegaran las referencias, los hashes de valor-clave planos eran lo mejor que podíamos hacer, pero las referencias permitían

 my %personal_info = ( "Cleaver", { "FIRST", "Ward", "SPOUSE", "June", }, "Flintstone", { "FIRST", "Fred", "SPOUSE", "Wilma", }, "Bunker", { "FIRST", "Archie", "SPOUSE", "Edith", }, ); 

Internamente, las claves y 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 hashes "multidimensionales". 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} 

Eso es un montón de tipeo si quieres saber más sobre Fred, así que puedes tomar una referencia como una especie de cursor:

 $fred = $personal_info{Flintstone}; print "Fred's wife is $fred->{SPOUSE}\n"; 

Como $fred en el fragmento de arriba es un hashref, la flecha es necesaria. Si lo excluyes pero sabiamente habilitado use strict para ayudarte a detectar este tipo de errores, el comstackdor 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 nulas. Los punteros en C y C ++ requieren desreferenciación y también lo hacen las referencias en Perl.

Los parámetros de la función C y C ++ tienen una semántica de paso a paso: son solo copias, por lo que las modificaciones no se transmiten 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 descartará tan pronto como regrese el submarinista.

Tenga en cuenta también el uso de la "coma de grasa" ( => ) arriba. Automatiza la cadena a su izquierda y hace que las inicializaciones de hash sean menos ruidosas sintácticamente.

A continuación, se muestra cómo puede usar una referencia hash y 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"; 

También vea perldoc perldsc .

Un hash es un tipo de datos básico en Perl. Utiliza claves para acceder a sus contenidos.

Una referencia de hash es la abreviatura de una referencia a un hash. Las referencias son escalares, que son valores simples. Es un valor escalar que contiene esencialmente, un puntero al propio hash real.

Link: diferencia entre hash y hash ref en perl – Ubuntu Forums

Una diferencia también está en la syntax para eliminar. Al igual que C, perl funciona así para Hashes:

 delete $hash{$key}; 

y para Hash References

 delete $hash_ref->{$key}; 

El Perl Hash Howto es un gran recurso para entender Hashes versus Hash con Hash References

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 desde la línea de comando de su computadora.

Una referencia es un valor escalar que se refiere a una matriz completa o a una matriz completa (o a casi cualquier otra cosa). Los nombres son un tipo de referencia con el que ya estás familiarizado. Piensa 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 progtwig 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 hash. Son nombres internos y privados 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 usted siempre 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.