Pregunta

Una lista de asignación en el contexto escalar devuelve el número de elementos en el lado derecho:

scalar(my ($hello, $there, $world) = (7,8)); #evaluates to 2

¿Por qué evaluar el lado derecho y producir 2, en lugar de la nueva definición de la lista que está siendo evaluado y regresando el 3?

Para mí, parece como $hello consigue 7, $there se mete 8, y $world consigue undef, a continuación, la lista es evaluado en escalar el contexto, lo que resultaría en 3, ya que es el número de elementos en la lista ($hello $there $world).Parece extraño para mí que el contexto afecta a la parte de la expresión evaluada es devuelto:

my $greeting = (($hello, $there, $world) = (7,8)); #2

my @greeting = (($hello, $there, $world) = (7,8));
my $greeting_length = @greeting; #3
¿Fue útil?

Solución

Se documenta para contar los elementos de la derecha en perlop (la última frase en la Asignación a los Operadores de la sección):

Del mismo modo, una lista de asignación en la lista contexto se produce la lista de lvalues asignado, y una lista de asignación en el contexto escalar devuelve el número de elementos producidos por la expresión en el lado derecho de la asignación.

La razón por la que funciona como que es lo que puede escribir cosas como esta:

while (my ($key, $value) = each %hash) { ... }

Si se cuenta el número de elementos en el lado izquierdo de la asignación, que sería un bucle infinito.

Si usted piensa acerca de ello, el número de elementos en el lado izquierdo es la misma que en el lado derecho o es una constante (cuando se va a asignar a una lista de escalares).En el primer caso, no hace ninguna diferencia qué lado usted de contar, y en el segundo caso, contando el lado derecho es más útil.

Por otro lado, en la lista contexto, el operador de asignación devuelve la lista de la izquierda, debido a que es más útil.Si se utiliza en un contexto en el que modifica los elementos de la lista que desea modificar las variables de las que se le asignan.

Re:tu comentario En tu ejemplo, (7,8) es una lista con dos elementos, por lo que el operador de asignación devuelve 2.Cuando se asigna una lista más corta a una larga lista de escalares, el lado derecho no es "collar" con undef antes de la asignación sucede.En su lugar, las variables que no tienen un valor asociado con ellos de la mano derecha de la lista se restablecen a sus valores por defecto.Para una variable escalar, que undef.Para las matrices, que es una matriz vacía.Para hash, que es un hash vacío.

Otros consejos

Me parece extraño que se evalúe los efectos de contexto de qué lado:

No lo hace. Ambas partes (operandos) del operador de asignación de la lista evaluaron, y si la asignación de la lista se evalúa en contexto escalar o contexto de la lista no afecta la evaluación de los operandos.

Si una asignación de lista se evalúa en contexto escalar o contexto de la lista solo afecta el valor que devuelve.

He creado previamente Operador de asignación escalar vs de la lista, que intenta aclarar las diferencias entre los dos operadores de asignación y cómo se comportan en el contexto escalar y en la lista.

¿Por qué evalúa el lado derecho y produce 2, en lugar de que la lista recién definida se evalúe y regrese 3?

Porque eso es lo que la definición del idioma dice que debería hacer, porque eso es lo que Larry Wall decidió que debería hacer.

Para mí, parece que $ hello obtiene 7, $ obtiene 8 y $ world obtiene undef, entonces esa lista se evalúa en contexto escalar

No, Perl no funciona de esa manera. Asume que el contexto escalar es solo una conversión del resultado que se habría obtenido en el contexto de la lista a un escalar contando el número de elementos en el resultado de la lista, pero eso simplemente no es correcto ... el contexto escalar significa que una operación (en este caso la asignación) debe producir un resultado escalar, y a menudo hay resultados escalares que son más útiles que solo el número de elementos en el resultado del contexto de la lista, y que varía de operador a operador ... debe verificar la documentación Para lo que el Scalar produce; No es uniforme. Para la asignación de listas, el valor escalar es el número de elementos en el lado derecho, porque eso es mucho más útil que el número de receptores, lo cual es constante. p.ej, if (($a, $b) = $s =~ /$re/) es cierto si la coincidencia produjo resultados, en lugar de ser siempre cierto porque hay dos receptores.

Me parece extraño que el contexto afecte qué parte de la expresión evaluada se devuelve

Hay cosas mucho más extrañas en Perl. Ese sentimiento de rareza proviene de un desajuste entre los modelos ... En este caso, su expectativa de ortogonalidad y su creencia de que "contexto escalar" es un operador en las listas, el diseño pragmático de Perl y la realidad de que "contexto escalar" establece un contexto que determina qué resultado para producir. Tenga en cuenta que puede escribir sus propias funciones que producen resultados completamente diferentes dependiendo del contexto de la llamada.

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