2010-05-15 19 views
8

Estoy tratando de descifrar un código Perl con el que no estoy familiarizado, de alguna manera relacionado con HashRef. Estoy usando Amazon :: S3, pero mi pregunta es una pregunta general de Perl. Ver el código de abajo:¿Qué significa cuando un método Perl devuelve un "hashref"?

use Amazon::S3; 
my $s3 = Amazon::S3->new(...); 
my $response = $s3->buckets; 

Documentación EFS (aquí), sobre S3-> cubos:

Returns undef on error, else HASHREF of results 

La siguiente línea está funcionando para mí, pero yo no entiendo por qué:

for $b in (@ { $response->{buckets} }) { 
    print "bucket: " . $b->bucket . "\n"; 
} 

Estoy desconcertado por cada operador en la primera línea.

¿Qué tipo de exactamente son $response, $respone->{bucket}. Parece que la expresión dentro del for es una matriz, pero no entiendo esta sintaxis: @{ ... }?

Respuesta

10

Vamos a ir a través de él pieza por pieza.

$s3 es su objeto S3. $s3->buckets llama al método buckets en ese objeto, y almacenamos los resultados en $response. Como dicen los documentos, los resultados son una referencia hash; una referencia es un escalar que apunta a otro valor. Si está familiarizado con los punteros, la idea es la misma.

Si tuviéramos un hash simple %response, podríamos obtener la clave buckets en el hash diciendo $response{buckets}. Dado que tenemos una referencia de hash , tenemos que usar el operador de desreferencia (->) para obtener la clave, por lo que se convierte en $response->{buckets}.

Pero aún no hemos terminado. $response->{buckets} es sí mismo una referencia, en este caso, una matriz de referencia. Aquí vemos otra forma de desreferenciación. Podríamos, si quisiéramos obtener solo un ítem en la matriz referenciada, digamos $response->{buckets}[0], por ejemplo.Pero queremos toda la lista, entonces usamos el operador @ para eliminar la referencia de la matriz completa. Como nuestra referencia de matriz está contenida en una estructura compleja, usamos curlies para contener la expresión que tiene la referencia. Así que @{ $response->{buckets} } nos consigue la matriz.

Eso está haciendo mucho en una sola declaración.

Para más información sobre referencias, que puede ser uno de los temas más difíciles de aprender en Perl, consulte lo siguiente:

  • perlreftut - Referencia Perl tutorial
  • perldsc - estructuras de datos Perl cookbook
  • perllol - Todo sobre las matrices de matrices
  • perlref - La principal documentación de referencias de Perl
+0

Muchas gracias. Muy útil. – Uri

+0

perlreftut perlreftut perlreftut :) – hobbs

-1

Puede examinar el tipo de variable con la función ref().

@ {...} significa "de-referencia escalar ... como matriz". Así que si vas de esta manera: my $ aref = ['a', 'b']; acceder a @ {$ aref} arrojará la matriz ('a', 'b').

De manera similar% {...} para referencias hash.

Consulte perlreftut para obtener más información.

4

¡Bienvenido al mundo de las referencias de Perl! Va a encontrar el reference tutorial muy útil.

La sintaxis @{...} toma un valor escalar e intenta desviarla a una matriz. También hay %{...}, que intenta desviar la referencia a un hash. Los curlies son opcionales, por lo que también puede escribir @$reference o %$reference para obtener el mismo efecto. Algunas personas los encuentran visualmente útiles cuando la referencia está dentro de un hash o una matriz, como es el caso aquí.

Para ayudarlo a comprender un poco más la estructura de datos, intente utilizar algo como Data :: Dumper.

use Data::Dumper; 
print Dumper $response; 
print Dumper $response->{buckets}; 
# The docs say that buckets is a hashref. It also happens that 
# you can coerce a hash into an array. Let's treat it as a hash 
# and see what's inside it, manually. The Dumper call above should 
# have already provided the structure to you, though. 
foreach my $k (keys %{$response->{buckets}}) { 
    print "$k => " . Dumper $response->{buckets}->{$k} 
} 
Cuestiones relacionadas