strawberry logo lane historia example compilador perl

logo - perl vs python



Forzar un contexto de lista en Perl (3)

Está confundido porque piensa = es un solo operador, mientras que puede dar como resultado dos operadores diferentes: un operador de asignación de lista o un operador de asignación escalar. Mini-Tutorial: Escalar vs Operador de Asignación de Listas explica las diferencias.

my $b = (33,22,11); ------------------ Scalar assign in void context. ---------- List literal in scalar context. Returns last. my @b = (33,22,11); ------------------ List assign in void context. ---------- List literal in list context. Returns all. my $b = ( () = (33,22,11) ); --------------------------- Scalar assign in void context. ------------------- List assign in scalar context. Returns count of RHS ---------- List literal in list context. Returns all. my @b = ( () = (33,22,11) ); --------------------------- List assign in void context. ------------------- List assign in list context. Returns LHS. ---------- List literal in list context. Returns all.

En cuanto a su título, forzar el contexto de la lista es imposible por decir. Si una función devuelve una lista cuando se espera un escalar, resulta en valores adicionales en la pila, lo que lleva a los operadores a obtener los argumentos incorrectos.

Sin embargo, puedes hacer algo como:

( EXPR )[0]

o

( EXPR )[-1]

EXPR a EXPR en contexto de lista, pero el conjunto devolverá solo un elemento de la lista devuelta.

Intento entender el contexto de Perl y tropecé con una roca;

Dado el código;

#!/usr/bin/perl my $b = (33,22,11); print "$b/n"; my $b = () = (33,22,11); print "$b/n"; my @b = (33,22,11); print "@b/n"; my @b = () = (33,22,11); print "@b/n";

Los resultados son (la última línea está en blanco);

11 3 33 22 11 <>

Dado que la segunda impresión arrojó la longitud de la lista, asumí que en algún lugar se generó una matriz, ya que una matriz en un contexto escalar evalúa su longitud. Pero la cuarta impresión parece desmentir esa suposición. Esperaba ver impreso ''33 22 11'' pero no recibí nada en su lugar. ¿Que esta pasando aqui?


La asignación de lista en contexto escalar devuelve la cantidad de elementos en el lado derecho (caso 2). El caso 4 primero asigna (33, 22, 11) a () , y luego asigna () (cuyo valor no ha cambiado) a @b .


Respondiendo la pregunta implícita en el título:

Perl proporciona un builtin scalar para forzar el contexto escalar cuando de otro modo no se usaría; una list similar incluida no existe, me imagino en gran parte porque podría significar una serie de cosas diferentes, por ejemplo:

list { code to execute in list context };

podría definirse:

sub list (&) { scalar( () = $_[0]->() ) } # return count of elements sub list (&) { ( $_[0]->() )[0] } # return first element sub list (&) { ( $_[0]->() )[-1] } # return last element sub list (&) { for( $_[0]->() ) {} } # return nothing

Respondiendo el cuerpo de la pregunta:

Cuando se confunde por contexto, recuerde que los operadores imponen contexto en operandos, no al revés. En su caso de problema, tiene una asignación escalar, asignando a un escalar el resultado de una asignación de lista, lo que coloca la asignación de lista en un contexto escalar. Para saber qué sucede, simplemente busque lo que devolverá la asignación de la lista en contexto escalar. (En general, los operadores devuelven lo que tiene el sentido más común, lo que significa que no hay una regla fácil de recordar que se aplique a todos los operadores).