Pregunta

Dado que las matrices y los hashes solo pueden contener escalares en Perl, ¿por qué tiene que usar $ para decirle al intérprete que el valor es un escalar al acceder a elementos de matriz o hash?En otras palabras, suponiendo que tienes una matriz @myarray y un hash %myhash, ¿por qué necesitas hacer:

$x = $myarray[1];
$y = $myhash{'foo'};

en lugar de simplemente hacer:

$x = myarray[1];
$y = myhash{'foo'};

¿Por qué lo anterior es ambiguo?

¿No sería un código Perl ilegal si fuera algo más que $ en ese lugar?Por ejemplo, ¿no son ilegales todos los siguientes elementos en Perl?

@var[0];
@var{'key'};
%var[0];
%var{'key'};
¿Fue útil?

Solución

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 que debe especificar si desea obtener un valor único del hash / array o no.

Otros consejos

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

Entonces myarray llama a una subrutina pasándole una referencia a una matriz anónima que contiene un único elemento, 1.

Esa es otra razón por la que necesita el sigilo en un acceso de matriz.

El sigilo le da el tipo de retorno del contenedor. Entonces, si algo comienza con @, sabes 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 lenguajes humanos tienen conceptos muy similares.

Sin embargo, muchos programadores encontraron eso confuso, por lo que Perl 6 usa un sigilo invariante.

En general, el compilador de Perl 5 quiere saber en tiempo de compilación si algo está en la lista o en un contexto escalar, por lo que sin el sigilo inicial algunos términos serían ambiguos.

Este es Perl válido: @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 pueden ser indexadas por números y las otras dos (%var[0] and %var['key']) no son Perl válidos porque los sectores hash utilizan {} para indexar el hash.

@var{'key'} y @var{0} Sin embargo, ambas son porciones de hash válidas.Evidentemente no es normal tomar trozos de longitud uno, pero ciertamente es válido.

Ver la sección de corte de perldata perldocpara obtener más información sobre el corte en Perl.

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 tiene que 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 de Perl en otros idiomas.

Puedo pensar de una manera que

$x = myarray[1];

es ambiguo, ¿y si quisieras una matriz llamada m?

$x = m[1];

¿Cómo puedes distinguir eso aparte de una coincidencia de expresiones regulares?

En otras palabras, la sintaxis está ahí para ayudar al intérprete de Perl, bueno, ¡interprete!

En Perl 5 (para ser cambiado en Perl 6) un sigilo indica el contexto de su expresión.

  • Desea un escalar particular de un hash, por lo que es $hash{key}.
  • Desea que el valor de una ranura en particular salga de una matriz, por lo que es $array[0]

Sin embargo, como lo señala zigdon, los cortes son legales. Interpretan esas expresiones en un contexto list .

  • Desea una lista de 1 valor en un hash @hash{key} funciona
  • Pero también funcionan listas más grandes, como @hash{qw<key1 key2 ... key_n>}.

  • Desea un par de ranuras de una matriz @array[0,3,5..7,$n..$n+5] funciona

  • @array[0] es una lista de tamaño 1.

No hay " contexto hash " ;, por lo que ni %hash{@keys} ni %hash{key} tienen significado.

Entonces tienes "@" + "array[0]" < = > < sigil = contexto > + < expresión de indexación > como la expresión completa

El sigilo proporciona el contexto para el acceso:

  • $ significa contexto escalar (un escalar variable o un solo elemento de un hash o una matriz)
  • @ significa contexto de lista (una matriz completa o una porción de un hash o una matriz)
  • % es un hash completo

En Perl 5 necesita los sigilos ($ y @) porque la interpretación predeterminada del identificador de palabras desnudas es la de una llamada de subrutina (eliminando así la necesidad de usar & amp; en la mayoría de los casos).

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