Question

Je veux écrire une petite fonction "DBQuery" en perl pour pouvoir avoir des one-liners qui envoient une instruction SQL et reçoivent en retour un tableau de hachages, c'est-à-direun jeu d'enregistrements.Cependant, je rencontre un problème avec la syntaxe Perl (et probablement un étrange problème de pointeur/référence) qui m'empêche de regrouper les informations du hachage que je reçois de la base de données.L'exemple de code ci-dessous illustre le problème.

Je peux extraire les données "Jim" d'un hachage dans un tableau avec cette syntaxe :

print $records[$index]{'firstName'}

renvoie "Jim"

mais si je copie d'abord l'enregistrement de hachage du tableau dans sa propre variable de hachage, alors étrangement, je ne peux plus accéder aux données de ce hachage :


    %row = $records[$index];
    $row{'firstName'};

renvoie "" (vide)

Voici l'exemple de code complet montrant le problème.Toute aide est appréciée :


my @records = (
   {'id' => 1, 'firstName' => 'Jim'},
   {'id' => 2, 'firstName' => 'Joe'}
);
my @records2 = ();

$numberOfRecords = scalar(@records);
print "number of records: " . $numberOfRecords . "\n";
for(my $index=0; $index < $numberOfRecords; $index++) {

   #works
   print 'you can print the records like this: ' . $records[$index]{'firstName'} . "\n";

   #does NOT work
   %row = $records[$index];
   print 'but not like this: ' . $row{'firstName'} . "\n";

} 
Était-ce utile?

La solution

La structure de données imbriquée contient un hachage référence, pas un hachage.

# Will work (the -> dereferences the reference)
$row = $records[$index];
print "This will work: ", $row->{firstName}, "\n";

# This will also work, by promoting the hash reference into a hash
%row = %{ $records[$index] };
print "This will work: ", $row{firstName}, "\n";

Si jamais vous êtes confronté à une structure de données Perl approfondie, vous pourriez bénéficier de son impression en utilisant Données : Dumper pour l'imprimer sous une forme lisible par l'homme (et analysable en Perl).

Autres conseils

Le tableau de hachages ne contient pas réellement de hachages, mais plutôt un les références à un hachage.Cette ligne:

%row = $records[$index];

attribue %row avec une entrée.La clé est la scalaire:

   {'id' => 1, 'firstName' => 'Jim'},

Qui est une référence au hachage, alors que la valeur est vide.

Ce que vous voulez vraiment faire, c'est ceci :

$row = $records[$index];
$row->{'firstName'};

ou sinon:

$row = %{$records[$index];}
$row{'firstName'};

D'autres ont commenté les hachages par rapport aux hashrefs.Une autre chose qui, à mon avis, devrait être mentionnée est votre fonction DBQuery - il semble que vous essayez de faire quelque chose qui est déjà intégré au DBI ?Si je comprends bien votre question, vous essayez de reproduire quelque chose comme selectall_arrayref:

Cette méthode utilitaire combine « prepare », « execute » et « fetchall_arrayref » en un seul appel.Il renvoie une référence à un tableau contenant une référence à un tableau (ou un hachage, voir ci-dessous) pour chaque ligne de données récupérées.

Pour ajouter aux belles réponses ci-dessus, permettez-moi d'ajouter que vous devriez toujours, toujours, toujours (oui, trois "toujours") utiliser "utiliser les avertissements" en haut de votre code.Si vous l'aviez fait, vous auriez reçu l'avertissement "Référence trouvée là où une liste de taille paire est attendue à la ligne 1 -e".

ce que vous avez réellement dans votre tableau est un hashref, pas un hachage.Si vous ne comprenez pas ce concept, cela vaut probablement la peine de lire le référence perl Documentation.

pour obtenir le hachage, vous devez le faire

my %hash = %{@records[$index]};

Par exemple.

my @records = (
     {'id' => 1, 'firstName' => 'Jim'}, 
     {'id' => 2, 'firstName' => 'Joe'}
  );

  my %hash = %{$records[1]};

  print $hash{id}."\n";

Bien que.Je ne sais pas pourquoi vous voudriez faire cela, à moins que ce ne soit à des fins académiques.Sinon, je recommanderais soit fetchall_hashref/fetchall_arrayref dans le module DBI, soit d'utiliser quelque chose comme Class::DBI.

Notez également qu'un bon idiome Perl à utiliser est

for my $rowHR ( @records ) {
   my %row = %$rowHR; 
   #or whatever...
}

pour parcourir la liste.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top