2010-05-22 11 views
7

En perl, los paréntesis se utilizan para anular precedencia (como en la mayoría de los lenguajes de programación) así como para crear listas. ¿Cómo puedo saber si un par particular de parens será tratado como una construcción de agrupación o una lista de un elemento?¿Cómo puedo saber si un conjunto de parens en código Perl actuará como agrupamiento de parens o formará una lista?

Por ejemplo, estoy bastante seguro de que esta es una lista escalar y no de un elemento: (1 + 1)
Pero, ¿qué pasa con las expresiones más complejas? ¿Hay alguna manera fácil de decirlo?

+0

Supongo que me preocupa sobre todo la asignación accidental de una lista de un elemento que contiene un resultado en lugar del resultado a un escalar. Pero si estoy leyendo las respuestas correctamente, esto es realmente imposible, a menos que haga algo como '$ x = @ {[1 + 1]};'. Parece que asignar una lista a un escalar es diferente de asignar una matriz a un escalar. ¿Qué sucede si asigna una lista que contiene una matriz a un escalar? '$ x = (@list);' –

+0

En una asignación, el lado izquierdo determina el contexto en el que se evaluará el lado derecho. Por lo tanto, cuando asigna una matriz a una variable escalar, la matriz se evalúa en contexto escalar. Una matriz evaluada en contexto escalar devuelve la cantidad de elementos en la matriz. Ambos ejemplos en su comentario caen bajo esa categoría. También observe que aquí estamos hablando de la evaluación de una matriz en contexto escalar. No estamos hablando de una lista en contexto escalar, porque no hay listas en contexto escalar. – FMc

+0

Supongo que siempre he pensado que las listas y las matrices son básicamente equivalentes e intercambiables, pero no lo son. –

Respuesta

16

tres principios clave son útiles aquí:

El contexto es rey. La evaluación de su ejemplo (1 + 1) depende del contexto.

$x = (1 + 1); # Scalar context. $x will equal 2. Parentheses do nothing here. 
@y = (1 + 1); # List context. @y will contain one element: (2). 
       # Parens do nothing (see below), aside from following 
       # syntax conventions. 

En un contexto escalar, no hay tal cosa como una lista. Para ver esto, intente asignar lo que aparece para ser una lista a una variable escalar. La forma de pensar sobre esto es centrarse en el comportamiento del operador de coma: en el contexto escalar, evalúa su argumento de la izquierda, descarta ese valor, luego evalúa su argumento correcto y devuelve ese valor. En el contexto de la lista, el operador de coma inserta ambos argumentos en la lista.

@arr = (12, 34, 56); # Right side returns a list. 

$x = (12, 34, 56); # Right side returns 56. Also, we get warnings 
         # about 12 and 34 being used in void context. 

$x = (@arr, 7);  # Right side returns 7. And we get a warning 
         # about using an array in a void context. 

Los paréntesis no crean listas. El operador de coma crea la lista (siempre que estemos en el contexto de la lista). Al escribir listas en código Perl, los paréntesis son necesarios por razones de precedencia, no por motivos de creación de listas. Unos pocos ejemplos:

  • Los paréntesis no tienen ningún efecto: estamos evaluando una matriz en escalar contexto, por lo que el lado derecho devuelve el tamaño de la matriz.

    $x = (@arr); 
    
  • Los paréntesis no son necesarios para crear una lista con un elemento.

    @arr = 33;   # Works fine, with @arr equal to (33). 
    
  • Pero se necesitan paréntesis con varios elementos, por razones de prioridad.

    @arr = 12, 34, 56; # @arr equals (12). And we get warnings about using 
            # 34 and 56 in void context. 
    
8
  1. Contexto.
  2. Los paréntesis no tienen la función que usted cree que tienen al crear una lista.

Ejemplos:

$x = 1 + 1; # $x is 2. 
$x = (1 + 1); # $x is 2. 
@x = 1 + 1; # @x is (2). 
@x = (1 + 1); # @x is (2). 

$x = (1 + 1, 1 + 2); # $x is 3. 
@x = (1 + 1, 1 + 2); # @x is (2, 3). 

En términos generales, en el contexto de lista el operador de coma separa los elementos de una lista; en contexto escalar, el operador de coma es la "coma en serie" C, que evalúa sus lados izquierdo y derecho, y devuelve el valor del lado derecho. En el contexto escalar, los paréntesis agrupan las expresiones para anular el orden de las operaciones, y en el contexto de la lista, los paréntesis hacen ... exactamente lo mismo, realmente.La razón por la que son relevantes en la asignación de matrices es la siguiente:

# Comma has precedence below assignment. 
# @a is assigned (1), 2 and 3 are discarded. 
@a = 1, 2, 3; 

# @a is (1, 2, 3). 
@a = (1, 2, 3); 

cuanto a su pregunta "¿es un escalar o una lista de un solo elemento", no es sólo una cuestión significativa para pedir de una expresión en forma aislada por el contexto En el contexto de la lista, todo es una lista; en contexto escalar, nada es.

Lectura recomendada: perlop, perldata, Programación Perl.

+0

Me gusta Deparse para mostrar ese operador de coma: perl -MO = Deparse -le 'my @s = 1,3,4; print "@s" ' BEGIN {$/= "\ n"; $ \ = "\ n"; } my (@s) = 1, '???', '???'; imprime "@s"; -e sintaxis OK –

Cuestiones relacionadas