2012-08-07 15 views
15

estoy mirando el siguiente código hash demostrando anidados:¿Por qué algunos hash se inicializan con llaves y algunos con paréntesis?

my %HoH = (
    flintstones => { 
     husband => "fred", 
     pal  => "barney", 
    }, 
    jetsons => { 
     husband => "george", 
     wife  => "jane", 
     "his boy" => "elroy", # Key quotes needed. 
    }, 
    simpsons => { 
     husband => "homer", 
     wife  => "marge", 
     kid  => "bart", 
    }, 
); 

Por qué es que la más superior de hash (a partir de la línea 1) se inicializa el uso de paréntesis, mientras que las sub-hashes se inicializan utilizando llaves ?

Viniendo de un fondo de pitón, debo decir que Perl es bastante extraño :).

Respuesta

21

Viniendo de un fondo Perl me parece Perl bastante extraño, también.

Use paréntesis para inicializar un hash (o una matriz). Un hash es un mapa entre un conjunto de cadenas y un conjunto de valores escalares.

%foo = ("key1", "value1", "key2", "value2", ...); # % means hash 
%foo = (key1 => "value1", key2 => "value2", ...); # same thing 

Braces se utilizan para definir una referencia de hash . Todas las referencias son valores escalares.

$foo = { key1 => "value1", key2 => "value2", ... }; # $ means scalar 

hashes son no valores escalares. Como los valores en un hash deben ser escalares, no es posible usar un hash como valor de otro hash.

%bar = (key3 => %foo);  # doesn't mean what you think it means 

Pero podemos utilizar referencias hash como valores de otro hash, porque las referencias hash son escalares.

$foo = { key1 => "value1", key2 => "value2" }; 
%bar = (key3 => $foo); 
%baz = (key4 => { key5 => "value5", key6 => "value6" }); 

Y es por eso que usted ve paréntesis que rodean una lista de listas con llaves.

+4

simplemente para la corrección ... si bien es cierto que 'key3 =>% foo' no hace lo que parece,' key3 => \% foo' añade una referencia y es una forma muy simple de hacer que haga lo que uno intentaría d en esa situación. –

2

En primer lugar, los parens no hacen más que cambiar la precedencia aquí. No tienen nada que ver con la creación de lista, la creación de hash o la inicialización de hash. Puede utilizar parens todo el operando del operador de la creación de hash,

{ (a => 1, b => 2) } 

y se pueden omitir las parens todo el operando del operador de asignación cuando precedencia permite.

sub f { return a => 1, b => 2 } 
my %hash = f(); 

En segundo lugar, uno no inicializar un hash utilizando { }; uno crea un hash usándolo. { } es equivalente a my %hash;, excepto que el hash es anónimo. En otras palabras,

{ EXPR } 

es básicamente el mismo que

do { my %anon = EXPR; \%anon } 

(pero no crea un ámbito léxico).

hashes Anónimo permite escribir

my %HoH = (
    flintstones => { 
     husband => "fred", 
     pal  => "barney", 
    }, 
    jetsons => { 
     husband => "george", 
     wife  => "jane", 
     "his boy" => "elroy", 
    }, 
    simpsons => { 
     husband => "homer", 
     wife  => "marge", 
     kid  => "bart", 
    }, 
); 

en lugar de

my %flintstones = (
    husband => "fred", 
    pal  => "barney", 
); 
my %jetsons = (
    husband => "george", 
    wife  => "jane", 
    "his boy" => "elroy", 
); 
my %simpsons = (
    husband => "homer", 
    wife  => "marge", 
    kid  => "bart", 
); 
my %HoH = (
    flintstones => \%flinstones, 
    jetsons  => \%jetsons, 
    simpsons => \%simpsons, 
); 
6

La diferencia esencial (....) se utiliza para crear un hash. {....} Se utiliza para crear un hash referencia

my %hash = (a => 1 , b => 2) ; 
my $hash_ref = { a => 1 , b => 2 } ; 

En un poco más de detalle - {....} hace una de hash anónimo y devuelve una referencia a la misma cosa que está asigned al escalar $hash_ref

editado para dar un poco más de detalle

Cuestiones relacionadas