web-dev-qa-db-fra.com

Quelle est la différence entre un hachage et une référence de hachage en Perl?

Je voudrais bien comprendre les hachages en Perl. Je dois utiliser Perl par intermittence depuis un certain temps et surtout chaque fois que je dois le faire, c'est principalement lié au traitement de texte.

Et à chaque fois, je dois gérer les hachages, ça s'embrouille. Je trouve la syntaxe très cryptique pour les hachages

Une bonne explication des hachages et des références de hachage, de leurs différences, lorsqu'ils sont requis, etc. serait très appréciée.

61
user855

Un hachage simple est proche d'un tableau. Leurs initialisations se ressemblent même. Tout d'abord le tableau:

@last_name = (
  "Ward",   "Cleaver",
  "Fred",   "Flintstone",
  "Archie", "Bunker"
);

Représentons maintenant les mêmes informations avec un hachage (aka tableau associatif):

%last_name = (
  "Ward",   "Cleaver",
  "Fred",   "Flintstone",
  "Archie", "Bunker"
);

Bien qu'ils portent le même nom, le tableau @last_name et le hachage %last_name sont complètement indépendants.

Avec le tableau, si nous voulons connaître le nom de famille d'Archie, nous devons effectuer une recherche linéaire:

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";

Avec le hachage, c'est beaucoup plus direct syntaxiquement:

print "Archie $last_name{Archie}\n";

Disons que nous voulons représenter des informations avec une structure légèrement plus riche:

  • Couperet (nom de famille)
    • Ward (prénom)
    • Juin (prénom du conjoint)
  • Flintstone
    • Fred
    • Wilma
  • Bunker
    • Archie
    • Edith

Avant l'arrivée des références, les hachages de valeur-clé plats étaient à peu près les meilleurs que nous pouvions faire, mais les références permettent

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

En interne, les clés et les valeurs de %personal_info sont tous des scalaires, mais les valeurs sont un type spécial de scalaire: les références de hachage, créées avec {}. Les références nous permettent de simuler des hachages "multidimensionnels". Par exemple, nous pouvons arriver à Wilma via

$personal_info{Flintstone}->{SPOUSE}

Notez que Perl nous permet d'omettre des flèches entre les indices, donc ce qui précède est équivalent à

$personal_info{Flintstone}{SPOUSE}

C'est beaucoup de saisie si vous voulez en savoir plus sur Fred, vous pouvez donc saisir une référence comme une sorte de curseur:

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

Car $fred dans l'extrait ci-dessus est un hachage, la flèche est nécessaire. Si vous le laissez de côté mais que vous l'utilisez judicieusement use strict pour vous aider à détecter ces types d'erreurs, le compilateur se plaindra:

Global symbol "%fred" requires explicit package name at ...

Les références Perl sont similaires aux pointeurs en C et C++, mais elles ne peuvent jamais être nulles. Les pointeurs en C et C++ nécessitent un déréférencement, tout comme les références en Perl.

Les paramètres des fonctions C et C++ ont une sémantique de passage par valeur: ce ne sont que des copies, donc les modifications ne reviennent pas à l'appelant. Si vous voulez voir les changements, vous devez passer un pointeur. Vous pouvez obtenir cet effet avec des références en Perl:

sub add_barney {
    my($personal_info) = @_;

    $personal_info->{Rubble} = {
        FIRST  => "Barney",
        SPOUSE => "Betty",
    };
}

add_barney \%personal_info;

Sans la barre oblique inverse, add_barney aurait obtenu une copie qui a été jetée dès le retour du sous.

Notez également l'utilisation de la "virgule grasse" (=>) au dessus de. Il cite automatiquement la chaîne à gauche et rend les initialisations de hachage moins syntaxiquement bruyantes.

87
Greg Bacon

Ce qui suit montre comment utiliser un hachage et une référence de hachage:

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";

Voir aussi perldoc perldsc .

16
Alan Haggai Alavi

Un hachage est un type de données de base en Perl. Il utilise des clés pour accéder à son contenu.

Une référence de hachage est l'abréviation d'une référence à un hachage. Les références sont des scalaires, c'est-à-dire des valeurs simples. Il s'agit d'une valeur scalaire qui contient essentiellement un pointeur sur le hachage lui-même.

Lien: différence entre hachage et référence de hachage en Perl - Forums Ubunt

Une différence réside également dans la syntaxe de suppression. Comme C, Perl fonctionne comme ceci pour Hashs:

delete $hash{$key};

et pour les références de hachage

delete $hash_ref->{$key};

Le Perl Hash Howto est une excellente ressource pour comprendre les hachages contre les hachages avec des références de hachage

Il y a aussi un autre lien ici qui a plus d'informations sur Perl et les références .

10
user195488

Voir perldoc perlreftut qui est également accessible sur la ligne de commande de votre propre ordinateur.

Une référence est une valeur scalaire qui fait référence à un tableau entier ou à un hachage entier (ou à à peu près n'importe quoi d'autre). Les noms sont un type de référence que vous connaissez déjà. Pensez au président des États-Unis: un sac de sang et d'os malpropre et peu pratique. Mais pour parler de lui, ou pour le représenter dans un programme informatique, tout ce dont vous avez besoin est la chaîne scalaire simple et pratique "Barack Obama".

Les références en Perl sont similaires aux noms des tableaux et des hachages. Ce sont les noms internes privés de Perl, vous pouvez donc être sûr qu'ils ne sont pas ambigus. Contrairement à "Barack Obama", une référence ne fait référence qu'à une seule chose, et vous savez toujours à quoi elle se réfère. Si vous avez une référence à un tableau, vous pouvez en récupérer l'intégralité. Si vous avez une référence à un hachage, vous pouvez récupérer l'intégralité du hachage. Mais la référence est toujours une valeur scalaire simple et compacte.

7
Sinan Ünür