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.

¿Fue útil?

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ón

C 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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top