hashes - perl hash of arrays
¿Por qué necesita $ al acceder a los elementos array y hash en Perl? (9)
Dado que las matrices y los hashes solo pueden contener escalas en Perl, ¿por qué tiene que usar $ para decirle al intérprete que el valor es escalar al acceder a elementos de matriz o hash? En otras palabras, suponiendo que tiene una matriz @myarray
y una hash %myhash
, ¿por qué debe hacer lo siguiente?
$x = $myarray[1];
$y = $myhash{''foo''};
en lugar de solo hacer:
$x = myarray[1];
$y = myhash{''foo''};
¿Por qué el anterior es ambiguo?
¿No sería ilegal el código de Perl si fuera cualquier cosa menos un $ en ese lugar? Por ejemplo, ¿no son todas las siguientes cosas ilegales en Perl?
@var[0];
@var{''key''};
%var[0];
%var{''key''};
Acabo de usar
my $x = myarray[1];
en un programa y, para mi sorpresa, esto es lo que sucedió cuando lo ejecuté:
$ perl foo.pl
Flying Butt Monkeys!
Eso es porque todo el programa se ve así:
$ cat foo.pl
#!/usr/bin/env perl
use strict;
use warnings;
sub myarray {
print "Flying Butt Monkeys!/n";
}
my $x = myarray[1];
Así que myarray llama a una subrutina pasando una referencia a una matriz anónima que contiene un solo elemento, 1.
Esa es otra razón por la que necesita el sigilo en un acceso de matriz.
El sigil proporciona el contexto para el acceso:
-
$
significa contexto escalar (una variable escalar o un elemento único de un hash o una matriz) -
@
significa contexto de la lista (una matriz completa o una rebanada de un hash o una matriz) -
%
es un hash completo
En Perl 5 (para ser modificado en Perl 6), un sigilo indica el contexto de su expresión.
- Usted quiere un escalar particular de un hash, así que es
$hash{key}
. - Desea el valor de una ranura particular de una matriz, por lo que es
$array[0]
.
Sin embargo, como lo señala zigdon, las rebanadas son legales. Interpretan esas expresiones en un contexto de lista .
- Desea que
@hash{key}
una lista de 1 valor en un hash@hash{key}
Pero también las listas más grandes funcionan igual, como
@hash{qw<key1 key2 ... key_n>}
.Quieres un par de máquinas tragamonedas de una matriz
@array[0,3,5..7,$n..$n+5]
funciona-
@array[0]
es una lista de tamaño 1.
No hay un "contexto hash", por lo que ni %hash{@keys}
ni %hash{key}
tienen significado.
Entonces tiene "@"
+ "array[0]"
<=> <sigil = contexto> + <expresión de indexación> como la expresión completa.
Esto es válido Perl: @var[0]
. Es una porción de matriz de longitud uno. @var[0,1]
sería una porción de matriz de longitud dos.
@var[''key'']
no es válido Perl porque las matrices solo se pueden indexar por números, y las otras dos ( %var[0] and %var[''key'']
) no son válidas Perl porque hash slices usan {} para indexar el hash.
@var{''key''}
y @var{0}
son dos hash válidos. Obviamente, no es normal tomar rodajas de longitud uno, pero ciertamente es válido.
Consulte la sección de división de perldoc perldoc para obtener más información sobre cómo dividir en Perl.
Las rebanadas no son ilegales:
@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};
Y sospecho que esa es parte de la razón por la cual necesita especificar si desea obtener un valor único del hash / array o no.
Puedo pensar en una forma en que
$x = myarray[1];
es ambiguo, ¿y si quisieras una matriz llamada m?
$x = m[1];
¿Cómo puedes decir que, aparte de un partido de expresiones regulares?
En otras palabras, la sintaxis está ahí para ayudar al intérprete de Perl, ¡bueno, a interpretar!
En Perl 5 necesita los sigilos ($ y @) porque la interpretación predeterminada del identificador de bareword es la de una llamada de subrutina (eliminando así la necesidad de usar & en la mayoría de los casos).
La gente ya ha señalado que puede tener sectores y contextos, pero los sigilos están ahí para separar las cosas que son variables de todo lo demás. No necesita conocer todas las palabras clave o nombres de subrutinas para elegir un nombre de variable sensible. Es una de las grandes cosas que extraño sobre Perl en otros idiomas.
El sigilo le proporciona el tipo de devolución del contenedor. Entonces, si algo comienza con @
, sabrá que devuelve una lista. Si comienza con $
, devuelve un escalar.
Ahora, si solo hay un identificador después del sigilo (como $foo
o @foo
, entonces es un acceso variable simple. Si es seguido por un [
, es un acceso en una matriz, si es seguido por un {
, es un acceso en un hash.
# variables
$foo
@foo
# accesses
$stuff{blubb} # accesses %stuff, returns a scalar
@stuff{@list} # accesses %stuff, returns an array
$stuff[blubb] # accesses @stuff, returns a scalar
# (and calls the blubb() function)
@stuff[blubb] # accesses @stuff, returns an array
Algunos idiomas humanos tienen conceptos muy similares.
Sin embargo, muchos programadores encontraron eso confuso, por lo que Perl 6 usa un sigilo invariable.
En general, el compilador de Perl 5 quiere saber en tiempo de compilación si algo está en la lista o en contexto escalar, por lo que sin el sigilo principal algunos términos se volverían ambiguos.