Pregunta

Quiero escribir una pequeña función "DBQuery" en Perl para poder tener frases ingeniosas que envíen una declaración SQL y reciban una serie de hashes, es decir.un conjunto de registros.Sin embargo, tengo un problema con la sintaxis de Perl (y probablemente algún problema extraño con el puntero/referencia) que me impide empaquetar la información del hash que obtengo de la base de datos.El código de muestra siguiente demuestra el problema.

Puedo obtener los datos "Jim" de un hash dentro de una matriz con esta sintaxis:

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

devuelve "Jim"

pero si primero copio el registro hash en la matriz a su propia variable hash, extrañamente ya no puedo acceder a los datos en ese hash:


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

devuelve "" (en blanco)

Aquí está el código de muestra completo que muestra el problema.Se agradece cualquier ayuda:


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

} 
¿Fue útil?

Solución

La estructura de datos anidada contiene un hash. referencia, no un hash.

# 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 alguna vez se le presenta una estructura de datos Perl profunda, puede beneficiarse imprimiéndola usando Datos::Dumper para imprimirlo en un formato legible por humanos (y analizable en Perl).

Otros consejos

La matriz de hashes en realidad no contiene hashes, sino más bien un referencias a un hash.Esta línea:

%row = $records[$index];

asigna% fila con una entrada.La clave es la escalar:

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

Que es una referencia al hash, mientras que el valor está en blanco.

Lo que realmente quieres hacer es esto:

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

si no:

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

Otros han comentado sobre hashes versus hashrefs.Otra cosa que creo que debería mencionarse es la función DBQuery: ¿parece que estás intentando hacer algo que ya está integrado en el DBI?Si entiendo tu pregunta correctamente, estás intentando replicar algo como seleccionarall_arrayref:

Este método de utilidad combina "preparar", "ejecutar" y "fetchall_arrayref" en una sola llamada.Devuelve una referencia a una matriz que contiene una referencia a una matriz (o hash, ver más abajo) para cada fila de datos obtenidos.

Para complementar las hermosas respuestas anteriores, permítame agregar que siempre, siempre, siempre (sí, tres "siempre") debe usar "advertencias de uso" en la parte superior de su código.Si lo hubiera hecho, habría recibido la advertencia "Se encontró referencia donde se esperaba una lista de tamaño par en -e línea 1".

lo que realmente tienes en tu matriz es un hashref, no un hash.Si no comprende este concepto, probablemente valga la pena leer el perlref documentación.

para obtener el hash que necesitas hacer

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

P.ej.

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

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

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

A pesar de.No estoy seguro de por qué querrías hacer esto, a menos que sea con fines académicos.De lo contrario, recomendaría fetchall_hashref/fetchall_arrayref en el módulo DBI o usar algo como Class::DBI.

También tenga en cuenta que un buen modismo de Perl es

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

para recorrer la lista.

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