¿Cuál es la diferencia entre los contextos escalares y de lista en Perl?
Pregunta
¿Cuál es la diferencia entre los contextos escalares y de lista en Perl y tiene esto algún paralelo en otros lenguajes como Java o JavaScript?
Solución
Varios operadores en Perl son sensibles al contexto y producen diferentes resultados de la lista y escalar contexto.
Por ejemplo:
my(@array) = (1, 2, 4, 8, 16);
my($first) = @array;
my(@copy1) = @array;
my @copy2 = @array;
my $count = @array;
print "array: @array\n";
print "first: $first\n";
print "copy1: @copy1\n";
print "copy2: @copy2\n";
print "count: $count\n";
Salida:
array: 1 2 4 8 16
first: 1
copy1: 1 2 4 8 16
copy2: 1 2 4 8 16
count: 5
Ahora:
-
$first
contiene 1 (el primer elemento de la matriz), debido a que los paréntesis en lamy($first)
proporcionan un contexto matriz, pero sólo hay espacio para un valor en$first
. - tanto
@copy1
y@copy2
contienen una copia de@array
, - y
$count
contiene 5 porque es un contexto escalar, y@array
se evalúa como el número de elementos de la matriz en un contexto escalar.
ejemplos más elaborados se podrían construir también (los resultados son un ejercicio para el lector):
my($item1, $item2, @rest) = @array;
my(@copy3, @copy4) = @array, @array;
No hay paralelo directo a la lista y contexto escalar en otros idiomas, que yo sepa.
Otros consejos
contexto escalar es lo que se obtiene cuando se está buscando un solo valor. contexto de la lista es lo que se obtiene cuando se está en busca de varios valores. Uno de los lugares más comunes para ver la distinción es cuando se trabaja con matrices:
@x = @array; # copy an array
$x = @array; # get the number of elements in an array
Otros operadores y funciones son sensibles al contexto, así:
$x = 'abc' =~ /(\w+)/; # $x = 1
($x) = 'abc' =~ /(\w+)/; # $x = 'abc'
@x = localtime(); # (seconds, minutes, hours...)
$x = localtime(); # 'Thu Dec 18 10:02:17 2008'
Como un operador (o función) se comporta en un contexto dado depende de la operadora. No hay reglas generales de cómo las cosas tienen que comportarse.
Usted puede hacer su propio contexto subrutinas sensibles utilizando la función wantarray
para determinar el contexto de llamada. Puede forzar una expresión a ser evaluada en contexto escalar utilizando la palabra clave scalar
.
Además de escalar y lista de contextos también verá (sin valor de retorno esperado) y contextos "vacíos" "booleano" (un verdadero falso valor / esperados) mencionados en la documentación.
Esto simplemente significa que un tipo de datos será evaluada basándose en el modo de la operación. Por ejemplo, una asignación a un escalar significa el lado derecho será evaluado como un escalar.
Creo que la mejor manera de comprender el contexto está aprendiendo sobre wantarray. Así imaginar que = es una subrutina que implementa wantarray:
sub = {
return if ( ! defined wantarray ); # void: just return (doesn't make sense for =)
return @_ if ( wantarray ); # list: return the array
return $#_ + 1; # scalar: return the count of the @_
}
Los ejemplos en este trabajo de post como si la subrutina arriba se llama pasando el lado derecho como parámetro.
En cuanto a los paralelos en otros idiomas, sí, todavía sostienen que prácticamente todas las ayudas de la lengua algo similar. El polimorfismo es similar en todos los lenguajes orientados a objetos. Otro ejemplo, Java convierte los objetos de cadena en ciertos contextos. Y cada lenguaje de script sin tipo que he usado tiene conceptos similares.