Un simple hachage est proche d'un tableau. Leurs initialisations se ressemblent même. D'abord le tableau :
@last_name = (
"Ward", "Cleaver",
"Fred", "Flintstone",
"Archie", "Bunker"
);
Maintenant, représentons la même information avec un hachage (ou 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 :
- Cleaver (nom de famille)
- Ward (prénom)
- June (prénom du conjoint)
- Pierrafeu
- Bunker
Avant l'arrivée des références, les hachages plats de valeurs-clés étaient à peu près le mieux 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 la commande {}
. Les références nous permettent de simuler des hachages "multidimensionnels". Par exemple, nous pouvons accéder à Wilma via
$personal_info{Flintstone}->{SPOUSE}
Notez que Perl nous permet d'omettre les flèches entre les sous-titres, donc ce qui précède est équivalent à
$personal_info{Flintstone}{SPOUSE}
Cela fait beaucoup de frappes si vous voulez en savoir plus sur Fred, vous pouvez donc prendre une référence comme une sorte de curseur :
$fred = $personal_info{Flintstone};
print "Fred's wife is $fred->{SPOUSE}\n";
Parce que $fred
dans le snippet ci-dessus est un hashref, la flèche est nécessaire. Si vous la laissez de côté mais que vous activez judicieusement use strict
pour vous aider à attraper ce genre 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 type "pass-by-value" : 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 les 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 inversée, add_barney
aurait eu une copie qui est jetée dès que le sous-marin revient.
Notez également l'utilisation de la "grosse virgule" ( =>
) ci-dessus. Il auto-cite la chaîne à sa gauche et rend les initialisations de hachage moins bruyantes syntaxiquement.