Il s'agit de la commande perldsc qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'un de nos multiples postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS
PROGRAMME:
Nom
perldsc - Livre de recettes sur les structures de données Perl
DESCRIPTION
Perl nous permet d'avoir des structures de données complexes. Vous pouvez écrire quelque chose comme ça et tout d'un
du coup, vous auriez un tableau à trois dimensions !
pour mon $x (1 .. 10) {
pour mon $y (1 .. 10) {
pour mon $z (1 .. 10) {
$AoA[$x][$y][$z] =
$x ** $y + $z ;
}
}
}
Hélas, aussi simple que cela puisse paraître, il y a en dessous une construction beaucoup plus élaborée que
rencontre l'oeil!
Comment l'imprimer ? Pourquoi ne pouvez-vous pas simplement dire « imprimer @AoA » ? Comment le triez-vous ? Comment
pouvez-vous le transmettre à une fonction ou en récupérer un à partir d'une fonction ? Est-ce un objet ?
Pouvez-vous l'enregistrer sur le disque pour le relire plus tard ? Comment accéder à des lignes ou des colonnes entières de
cette matrice ? Toutes les valeurs doivent-elles être numériques ?
Comme vous le voyez, il est assez facile de devenir confus. Bien qu'une petite partie du blâme pour
cela peut être attribué à l'implémentation basée sur les références, c'est vraiment plus dû à un
manque de documentation existante avec des exemples conçus pour le débutant.
Ce document se veut un traitement détaillé mais compréhensible des nombreux
sortes de structures de données que vous pourriez vouloir développer. Il devrait également servir de livre de cuisine de
exemples. De cette façon, lorsque vous devez créer l'une de ces structures de données complexes, vous pouvez
il suffit de pincer, de chaparder ou de voler un exemple d'entrée à partir d'ici.
Examinons en détail chacune de ces constructions possibles. Il y a des sections séparées sur
chacun des éléments suivants :
· tableaux de tableaux
· hachages de tableaux
· tableaux de hachages
· hachages de hachages
· constructions plus élaborées
Mais pour l'instant, examinons les problèmes généraux communs à tous ces types de structures de données.
Références
La chose la plus importante à comprendre sur toutes les structures de données en Perl, y compris
tableaux multidimensionnels - c'est que même s'ils peuvent apparaître autrement, Perl @ARRAYs et
Les % HASH sont tous unidimensionnels en interne. Ils ne peuvent contenir que des valeurs scalaires (c'est-à-dire un
chaîne, nombre ou référence). Ils ne peuvent pas contenir directement d'autres tableaux ou hachages, mais
contiennent à la place à d'autres tableaux ou hachages.
Vous ne pouvez pas utiliser une référence à un tableau ou à un hachage de la même manière que vous le feriez avec un vrai
tableau ou hachage. Pour les programmeurs C ou C++ peu habitués à faire la distinction entre les tableaux et
pointeurs vers le même, cela peut être déroutant. Si c'est le cas, considérez-le simplement comme la différence
entre une structure et un pointeur vers une structure.
Vous pouvez (et devriez) en savoir plus sur les références dans perlref. En bref, les références sont
plutôt comme des pointeurs qui savent vers quoi ils pointent. (Les objets sont aussi une sorte de référence,
mais nous n'en aurons pas besoin tout de suite - si jamais.) Cela signifie que lorsque vous avez
quelque chose qui vous semble être un accès à un tableau à deux ou plusieurs dimensions et/ou
hachage, ce qui se passe vraiment, c'est que le type de base est simplement une entité unidimensionnelle qui
contient des références au niveau suivant. C'est juste que tu peux utilisé c'est comme si c'était un
un bidimensionnel. C'est en fait la façon dont presque tous les tableaux multidimensionnels C fonctionnent
également.
$array[7][12] # tableau de tableaux
$array[7]{string} # tableau de hachages
$hash{string}[7] # hachage de tableaux
$hash{string}{'autre chaîne'} # hachage des hachages
Maintenant, parce que le niveau supérieur ne contient que des références, si vous essayez d'imprimer votre tableau dans
avec un simple impression() fonction, vous obtiendrez quelque chose qui n'a pas l'air très joli, comme
ce:
mon @AoA = ( [2, 3], [4, 5, 7], [0] );
affiche $AoA[1][2] ;
7
imprimer @AoA ;
TABLEAU(0x83c38)TABLEAU(0x8b194)TABLEAU(0x8b1d0)
C'est parce que Perl ne déréférence pas (jamais) implicitement vos variables. Si tu veux
obtenir la chose à laquelle une référence fait référence, alors vous devez le faire vous-même en utilisant
soit des indicateurs de saisie de préfixe, comme "${$blah}", "@{$blah}", "@{$blah[$i]}", ou bien
flèches de pointeur postfix, comme "$a->[3]", "$h->{fred}", ou même "$ob->method()->[3]".
COMMUNE ERREURS
Les deux erreurs les plus courantes commises lors de la construction de quelque chose comme un tableau de tableaux sont
soit en comptant accidentellement le nombre d'éléments, soit en prenant une référence au même
emplacement mémoire à plusieurs reprises. Voici le cas où vous obtenez juste le compte au lieu d'un
tableau imbriqué :
pour mon $i (1..10) {
mon @array = somefunc($i);
$AoA[$i] = @array; # TORT!
}
C'est juste le cas simple d'affecter un tableau à un scalaire et d'obtenir son élément
compter. Si c'est ce que vous voulez vraiment et vraiment, alors vous feriez bien d'envisager d'être
un peu plus explicite à ce sujet, comme ceci :
pour mon $i (1..10) {
mon @array = somefunc($i);
$compte[$i] = scalaire @array ;
}
Voici le cas où l'on prend encore et encore une référence au même emplacement mémoire :
# Soit sans strict, soit avec une portée externe my @array;
# déclaration.
pour mon $i (1..10) {
@array = unefonction($i);
$AoA[$i] = \@array; # TORT!
}
Alors, quel est le gros problème avec ça ? Ça a l'air bien, n'est-ce pas ? Après tout, je viens de dire
vous que vous avez besoin d'un tableau de références, alors bon sang, vous m'en avez fait une !
Malheureusement, même si cela est vrai, il est toujours cassé. Toutes les références dans @AoA font référence à
le très même endroit, et ils conserveront donc tous ce qu'il y avait en dernier dans @array ! C'est
similaire au problème démontré dans le programme C suivant :
#comprendre
principale() {
struct passwd *getpwnam(), *rp, *dp;
rp = getpwnam("root");
dp = getpwnam("démon");
printf("le nom du démon est %s\nle nom racine est %s\n",
dp->pw_name, rp->pw_name);
}
qui imprimera
le nom du démon est démon
le nom racine est démon
Le problème est que "rp" et "dp" sont des pointeurs vers le même emplacement en mémoire ! En C,
tu devrais te souvenir de malloc () vous un nouveau souvenir. En Perl, vous voudrez utiliser
le constructeur de tableau "[]" ou le constructeur de hachage "{}" à la place. Voici la bonne façon de
faire les fragments de code cassés précédents :
# Soit sans strict, soit avec une portée externe my @array;
# déclaration.
pour mon $i (1..10) {
@array = unefonction($i);
$AoA[$i] = [ @tableau ] ;
}
Les crochets font référence à un nouveau tableau avec un copier de ce qu'il y a dans @array au
moment de la mission. Voici ce que tu veux.
Notez que cela produira quelque chose de similaire, mais c'est beaucoup plus difficile à lire :
# Soit sans strict, soit avec une portée externe my @array;
# déclaration.
pour mon $i (1..10) {
@tableau = 0 .. $i;
@{$AoA[$i]} = @tableau ;
}
Est-ce la même? Eh bien, peut-être que oui, et peut-être pas. La différence subtile est que lorsque vous
attribuez quelque chose entre crochets, vous savez à coup sûr que c'est toujours une toute nouvelle référence
avec un nouveau copier des données. Quelque chose d'autre pourrait se passer dans ce nouveau cas avec le
"@{$AoA[$i]}" déréférencement sur le côté gauche de l'affectation. Tout dépend de
si $AoA[$i] n'avait pas été défini au départ, ou s'il contenait déjà un
référence. Si vous aviez déjà rempli @AoA avec des références, comme dans
$AoA[3] = \@un autre_tableau ;
Ensuite, l'affectation avec l'indirection sur le côté gauche utiliserait l'existant
référence qui était déjà là :
@{$AoA[3]} = @tableau ;
Bien sûr, cela pourra avoir l'effet "intéressant" de tabasser @another_array. (Ont
vous avez déjà remarqué que lorsqu'un programmeur dit que quelque chose est "intéressant", plutôt que
signifiant « intriguant », ils sont plus susceptibles de signifier que c'est « ennuyeux »,
« difficile », ou les deux ? :-)
Alors n'oubliez pas de toujours utiliser les constructeurs de tableau ou de hachage avec "[]" ou "{}", et
tout ira bien, même si ce n'est pas toujours d'une efficacité optimale.
Étonnamment, la construction d'apparence dangereuse suivante fonctionnera en fait très bien :
pour mon $i (1..10) {
mon @array = somefunc($i);
$AoA[$i] = \@tableau;
}
C'est parce que ma() est plus une déclaration d'exécution qu'une déclaration de compilation
/ se. Cela signifie que le ma() variable est refaite à chaque fois à travers la boucle.
Alors même s'il regards comme si vous stockiez à chaque fois la même référence de variable, vous
en fait pas ! Il s'agit d'une distinction subtile qui peut produire un code plus efficace à
le risque de tromper tous les programmeurs, sauf les plus expérimentés. Donc je conseille généralement
contre l'enseigner aux débutants. En fait, sauf pour passer des arguments aux fonctions, je
J'aime rarement voir l'opérateur gimme-a-reference (barre oblique inverse) beaucoup utilisé dans le code.
Au lieu de cela, je conseille aux débutants qu'ils (et la plupart d'entre nous) devraient essayer d'utiliser le
des constructeurs "[]" et "{}" bien plus faciles à comprendre au lieu de s'appuyer sur le lexique (ou
dynamique) et le comptage de références caché pour faire la bonne chose dans les coulisses.
En résumé:
$AoA[$i] = [ @array ]; # généralement le meilleur
$AoA[$i] = \@array; # périlleux ; à quel point my() était ce tableau ?
@{ $AoA[$i] } = @array; # beaucoup trop compliqué pour la plupart des programmeurs
MISE EN GARDE ON PRIORITÉ
En parlant de choses comme "@{$AoA[$i]}", ce qui suit est en fait la même chose :
$aref->[2][2] # effacer
$$aref[2][2] # déroutant
C'est parce que les règles de priorité de Perl sur ses cinq déréférenceurs de préfixe (qui ressemblent à
quelqu'un jure : "$ @ * % &") les lie plus étroitement que l'indice postfix
parenthèses ou accolades ! Ce sera sans aucun doute un grand choc pour le programmeur C ou C++,
qui a l'habitude d'utiliser *a[i] pour signifier ce que désigne le je suis élément de
"une". C'est-à-dire qu'ils prennent d'abord l'indice, et ensuite seulement déréférencent la chose à ce
indice. C'est bien en C, mais ce n'est pas C.
La construction apparemment équivalente en Perl, $$aref[$i] fait d'abord le deref de $aref,
lui faire prendre $aref comme référence à un tableau, puis le déréférencer, et enfin
te dire le je suis valeur du tableau pointé par $AoA. Si vous vouliez la notion C, vous auriez
devez écrire "${$AoA[$i]}" pour forcer le $AoA[$i] à être évalué avant le
déréférenceur "$" en tête.
POURQUOI VOUS DEVRAIT TOUJOURS "utilisation strict"
Si cela commence à sembler plus effrayant que cela ne vaut la peine, détendez-vous. Perl a quelques fonctionnalités à
vous aider à éviter ses pièges les plus courants. La meilleure façon d'éviter d'être confus est de
démarrez chaque programme comme ceci :
#!/usr/bin/perl -w
utiliser strict;
De cette façon, vous serez obligé de déclarer toutes vos variables avec ma() et aussi interdire
"déréférencement symbolique" accidentel. Donc si tu avais fait ça :
mon $aref = [
[ "fred", "barney", "cailloux", "bambam", "dino", ],
[ "homer", "bart", "marge", "maggie", ],
[ "george", "jane", "elroy", "judy", ],
];
print $aref[2][2] ;
Le compilateur signalerait immédiatement cela comme une erreur at compiler Paisible, parce que tu étais
accédant accidentellement à @aref, une variable non déclarée, et cela vous rappellerait ainsi de
écris à la place :
imprimer $aref->[2][2]
DÉBOGAGE
Vous pouvez utiliser la commande "x" du débogueur pour vider des structures de données complexes. Par exemple,
étant donné l'affectation à $AoA ci-dessus, voici la sortie du débogueur :
DB<1> x $AoA
$AoA = TABLEAU(0x13b5a0)
0 TABLEAU(0x1f0a24)
0 'fred'
1 'barney'
2 'cailloux'
3 'bamba'
4 'dinosaure'
1 TABLEAU(0x13b558)
0 'home'
1 'barth'
2 'marge'
3 'maggie'
2 TABLEAU(0x13b540)
0 'george'
1 'jane'
2 'elroy'
3 'juge'
CODE EXEMPLES
Présenté avec peu de commentaires (ceux-ci auront leurs propres pages de manuel un jour) voici de courts
exemples de code illustrant l'accès à divers types de structures de données.
TABLEAUX OF TABLEAUX
Déclaration of an TABLEAU OF TABLEAUX
@AoA = (
[ "fred", "barney"],
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
);
Generation of an TABLEAU OF TABLEAUX
# lecture du fichier
tandis que ( <> ) {
poussez @AoA, [ diviser ] ;
}
# appeler une fonction
pour $i ( 1 .. 10 ) {
$AoA[$i] = [ unefonction($i) ] ;
}
# utilisation des variables temporaires
pour $i ( 1 .. 10 ) {
@tmp = unefonction($i);
$AoA[$i] = [ @tmp ] ;
}
# ajouter à une ligne existante
push @{ $AoA[0] }, "wilma", "betty" ;
Accéder et Impression of an TABLEAU OF TABLEAUX
# un élément
$AoA[0][0] = "Fred" ;
# un autre élément
$AoA[1][1] =~ s/(\w)/\u$1/ ;
# imprime le tout avec les références
pour $aref ( @AoA ) {
print "\t [ @$aref ],\n" ;
}
# imprime le tout avec des indices
pour $i ( 0 .. $#AoA ) {
print "\t [ @{$AoA[$i]} ],\n" ;
}
# imprime le tout un à la fois
pour $i ( 0 .. $#AoA ) {
pour $j ( 0 .. $#{ $AoA[$i] } ) {
print "elt $i $j est $AoA[$i][$j]\n" ;
}
}
HACHÉS OF TABLEAUX
Déclaration of a HASH OF TABLEAUX
%HoA = (
silex => [ "fred", "barney" ],
jetsons => [ "george", "jane", "elroy" ],
simpsons => [ "homer", "marge", "bart" ],
);
Generation of a HASH OF TABLEAUX
# lecture du fichier
# silex : fred barney wilma dino
tandis que ( <> ) {
suivant sauf si s/^(.*?):\s*//;
$HoA{$1} = [ diviser ];
}
# lecture du fichier ; plus de temps
# silex : fred barney wilma dino
while ( $line = <> ) {
($qui, $rest) = split /:\s*/, $line, 2;
@fields = split ' ', $rest;
$HoA{$qui} = [ @champs ] ;
}
# appeler une fonction qui renvoie une liste
pour $group ( "simpsons", "jetsons", "flintstones" ) {
$HoA{$group} = [ get_family($group) ] ;
}
# de même, mais en utilisant les temps
pour $group ( "simpsons", "jetsons", "flintstones" ) {
@members = get_family($group);
$HoA{$groupe} = [ @members ] ;
}
# ajouter de nouveaux membres à une famille existante
push @{ $HoA{"flintstones"} }, "wilma", "betty" ;
Accéder et Impression of a HASH OF TABLEAUX
# un élément
$HoA{flintstones}[0] = "Fred" ;
# un autre élément
$HoA{simpsons}[1] =~ s/(\w)/\u$1/;
# imprimer le tout
foreach $family ( clés %HoA ) {
print "$famille : @{ $HoA{$famille} }\n"
}
# imprime le tout avec des indices
foreach $family ( clés %HoA ) {
imprimer « famille : » ;
foreach $i ( 0 .. $#{ $HoA{$famille} } ) {
print " $i = $HoA{$family}[$i]" ;
}
imprimer "\n" ;
}
# imprime le tout trié par nombre de membres
foreach $family ( sort { @{$HoA{$b}} <=> @{$HoA{$a}} } keys %HoA ) {
print "$famille : @{ $HoA{$famille} }\n"
}
# imprimer le tout trié par nombre de membres et nom
foreach $famille ( sort {
@{$HoA{$b}} <=> @{$HoA{$a}}
||
$a cmp $b
} clés %HoA )
{
print "$family: ", join(", ", sort @{ $HoA{$family} }), "\n" ;
}
TABLEAUX OF HACHÉS
Déclaration of an TABLEAU OF HACHÉS
@AoH = (
{
Plomb => "fred",
Ami => "barney",
},
{
Plomb => "george",
Femme => "jane",
Fils => "elroy",
},
{
Plomb => "home",
Femme => "marge",
Fils => "bart",
}
);
Generation of an TABLEAU OF HACHÉS
# lecture du fichier
# format : LEAD=fred AMI=barney
tandis que ( <> ) {
$rec = {} ;
pour le champ $ ( fractionné ) {
(clé $, valeur $) = diviser /=/, champ $ ;
$rec->{$key} = $value ;
}
poussez @AoH, $rec;
}
# lecture du fichier
# format : LEAD=fred AMI=barney
# pas de température
tandis que ( <> ) {
poussez @AoH, { diviser /[\s+=]/ } ;
}
# appeler une fonction qui renvoie une liste de paires clé/valeur, comme
# "plomb","fred","fille","cailloux"
tandis que (% champs = getnextpairset() ) {
poussez @AoH, { %fields } ;
}
# de même, mais en n'utilisant pas de variables temporaires
tandis que (<>) {
push @AoH, { parsepairs($_) } ;
}
# ajouter une clé/valeur à un élément
$AoH[0]{pet} = "dino" ;
$AoH[2]{pet} = "le petit assistant du père Noël";
Accéder et Impression of an TABLEAU OF HACHÉS
# un élément
$AoH[0]{lead} = "fred" ;
# un autre élément
$AoH[1]{chef} =~ s/(\w)/\u$1/ ;
# imprime le tout avec les références
pour $href ( @AoH ) {
imprimer "{ ";
pour $role ( clés %$href ) {
print "$role=$href->{$role} " ;
}
print "}\n" ;
}
# imprime le tout avec des indices
pour $i ( 0 .. $#AoH ) {
print "$i est { ";
pour $role ( clés %{ $AoH[$i] } ) {
print "$role=$AoH[$i]{$role} " ;
}
print "}\n" ;
}
# imprime le tout un à la fois
pour $i ( 0 .. $#AoH ) {
pour $role ( clés %{ $AoH[$i] } ) {
print "elt $i $role is $AoH[$i]{$role}\n" ;
}
}
HACHÉS OF HACHÉS
Déclaration of a HASH OF HACHÉS
%HoH = (
silex => {
plomb => "fred",
copain => "barney",
},
jetsons => {
plomb => "george",
femme => "jane",
"son garçon" => "elroy",
},
simpson => {
plomb => "home",
femme => "marge",
enfant => "bart",
},
);
Generation of a HASH OF HACHÉS
# lecture du fichier
# flintstones : lead=fred pal=barney wife=wilma pet=dino
tandis que ( <> ) {
suivant sauf si s/^(.*?):\s*//;
$qui = 1 $ ;
pour le champ $ ( fractionné ) {
(clé $, valeur $) = diviser /=/, champ $ ;
$HoH{$who}{$key} = $value ;
}
# lecture du fichier ; plus de temps
tandis que ( <> ) {
suivant sauf si s/^(.*?):\s*//;
$qui = 1 $ ;
$rec = {} ;
$HoH{$qui} = $rec ;
pour le champ $ ( fractionné ) {
(clé $, valeur $) = diviser /=/, champ $ ;
$rec->{$key} = $value ;
}
}
# appeler une fonction qui renvoie une clé, une valeur de hachage
pour $group ( "simpsons", "jetsons", "flintstones" ) {
$HoH{$groupe} = { get_family($group) } ;
}
# de même, mais en utilisant les temps
pour $group ( "simpsons", "jetsons", "flintstones" ) {
%membres = get_family($group);
$HoH{$group} = { %members } ;
}
# ajouter de nouveaux membres à une famille existante
%new_folks = (
femme => "wilma",
animal de compagnie => "dino",
);
pour $quoi (clés %new_folks) {
$HoH{flintstones}{$what} = $new_folks{$what} ;
}
Accéder et Impression of a HASH OF HACHÉS
# un élément
$HoH{flintstones}{femme} = "wilma";
# un autre élément
$HoH{simpsons}{lead} =~ s/(\w)/\u$1/;
# imprimer le tout
foreach $famille ( clés %HoH ) {
print "$famille: { ";
pour $role ( clés %{ $HoH{$family} } ) {
print "$rôle=$HoH{$famille}{$rôle} " ;
}
print "}\n" ;
}
# imprime le tout un peu trié
foreach $family ( clés de tri %HoH ) {
print "$famille: { ";
pour $role ( clés de tri %{ $HoH{$family} } ) {
print "$rôle=$HoH{$famille}{$rôle} " ;
}
print "}\n" ;
}
# imprime le tout trié par nombre de membres
foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$a}} }
touches %HoH )
{
print "$famille: { ";
pour $role ( clés de tri %{ $HoH{$family} } ) {
print "$rôle=$HoH{$famille}{$rôle} " ;
}
print "}\n" ;
}
# établir un ordre de tri (classement) pour chaque rôle
$ i = 0;
pour ( qw (femme principale fils fille copain animal de compagnie) ) { $rank{$_} = ++$i }
# maintenant imprimer le tout trié par nombre de membres
foreach $family ( sort { keys %{ $HoH{$b} } <=> keys %{ $HoH{$a} } }
touches %HoH )
{
print "$famille: { ";
# et imprimez-les selon l'ordre de classement
pour $role ( sort { $rank{$a} <=> $rank{$b} }
clés %{ $HoH{$family} } )
{
print "$rôle=$HoH{$famille}{$rôle} " ;
}
print "}\n" ;
}
AUTRES ÉLABORER RECORDS
Déclaration of AUTRES ÉLABORER RECORDS
Voici un exemple montrant comment créer et utiliser un enregistrement dont les champs sont de plusieurs types
trie :
$rec = {
TEXTE => $chaîne,
SEQUENCE => [ @old_values ],
RECHERCHE => { %some_table },
ThatCODE => \&some_function,
THISCODE => sous { $_[0] ** $_[1] },
POIGNÉE => \*STDOUT,
};
print $rec->{TEXT} ;
print $rec->{SEQUENCE}[0] ;
$last = pop @ { $rec->{SEQUENCE} } ;
print $rec->{RECHERCHE}{"clé"} ;
($first_k, $first_v) = chaque %{ $rec->{LOOKUP} } ;
$answer = $rec->{THATCODE}->($arg);
$réponse = $rec->{THISCODE}->($arg1, $arg2) ;
# attention aux accolades de bloc supplémentaires sur fh ref
print { $rec->{HANDLE} } "une chaîne\n" ;
utiliser FileHandle ;
$rec->{HANDLE}->rinçage automatique(1);
$rec->{HANDLE}->print(" une chaîne\n");
Déclaration of a HASH OF COMPLEXE RECORDS
%TV = (
silex => {
série => "pierres à fusil",
nuits => [ qw(lundi jeudi vendredi) ],
membres => [
{ nom => "fred", role => "lead", age => 36, },
{ name => "wilma", role => "wife", age => 31, },
{ nom => "cailloux", role => "enfant", age => 4, },
],
},
jetsons => {
série => "jetsons",
nuits => [ qw(mercredi samedi) ],
membres => [
{ name => "george", role => "lead", age => 41, },
{ name => "jane", role => "wife", age => 39, },
{ name => "elroy", role => "kid", age => 9, },
],
},
simpson => {
série => "simpsons",
nuits => [ qw(Lundi) ],
membres => [
{ name => "homer", role => "lead", age => 34, },
{ name => "marge", role => "wife", age => 37, },
{ name => "bart", role => "kid", age => 11, },
],
},
);
Generation of a HASH OF COMPLEXE RECORDS
# lecture du fichier
# cela se fait le plus facilement en faisant en sorte que le fichier lui-même soit
# dans le format de données brutes comme indiqué ci-dessus. perl est content
# pour analyser les structures de données complexes si elles sont déclarées en tant que données, donc
# parfois c'est plus simple de faire ça
# voici une construction pièce par pièce
$rec = {} ;
$rec->{série} = "pierres à fusil" ;
$rec->{nights} = [ find_days() ] ;
@membres = ();
# supposez ce fichier dans la syntaxe champ=valeur
tandis que (<>) {
%champs = diviser /[\s=]+/ ;
push @members, { %fields } ;
}
$rec->{membres} = [ @membres ];
# maintenant souviens-toi de tout
$TV{ $rec->{série} } = $rec;
################################################ #########
# maintenant, vous voudrez peut-être créer des champs supplémentaires intéressants qui
# inclure des pointeurs dans la même structure de données donc si
# changer une pièce, ça change partout, comme par exemple
# si vous vouliez un champ {kids} qui soit une référence
# à un tableau des enregistrements des enfants sans avoir de doublon
# enregistrements et ainsi mettre à jour les problèmes.
################################################ #########
foreach $famille (clés %TV) {
$rec = $TV{$famille} ; # pointeur temporaire
@enfants = ();
pour $person ( @{ $rec->{members} } ) {
if ($person->{rôle} =~ /enfant|fils|fille/) {
poussez @kids, $person ;
}
}
# RAPPELEZ-VOUS : $rec et $TV{$family} pointent vers les mêmes données !!
$rec->{kids} = [ @kids ];
}
# vous avez copié le tableau, mais le tableau lui-même contient des pointeurs
# aux objets non copiés. cela signifie que si vous faites en sorte que bart obtienne
# plus ancien via
$TV{simpsons}{enfants}[0]{age}++ ;
# alors cela changerait aussi dans
print $TV{simpsons}{members}[2]{age} ;
# parce que $TV{simpsons}{kids}[0] et $TV{simpsons}{members}[2]
# les deux pointent vers la même table de hachage anonyme sous-jacente
# imprimer le tout
foreach $famille ( clés %TV ) {
imprimez "la $famille" ;
print " est allumé pendant @{ $TV{$family}{nights} }\n" ;
print "ses membres sont :\n" ;
pour $who ( @{ $TV{$family}{members} } ) {
print " $who->{name} ($who->{role}), age $who->{age}\n" ;
}
print "il s'avère que $TV{$family}{lead} a " ;
print scalar ( @{ $TV{$family}{kids} } ), " enfants nommés " ;
print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
imprimer "\n" ;
}
Base de données Cravates
Vous ne pouvez pas facilement lier une structure de données à plusieurs niveaux (telle qu'un hachage de hachages) à un dbm
déposer. Le premier problème est que tous sauf GDBM et Berkeley DB ont des limitations de taille, mais
au-delà de cela, vous avez également des problèmes avec la façon dont les références doivent être représentées sur le disque.
Un module expérimental qui tente en partie de répondre à ce besoin est le MLDBM
module. Vérifiez votre site CPAN le plus proche comme décrit dans perlmodlib pour le code source de MLDBM.
Utiliser perldsc en ligne à l'aide des services onworks.net