2010-05-22 9 views
7

In perl, le parentesi sono utilizzate per la precedenza prevalente (come nella maggior parte dei linguaggi di programmazione) e per la creazione di elenchi. Come posso sapere se una particolare coppia di parenti sarà trattata come un costrutto di raggruppamento o una lista di un elemento?Come posso sapere se una serie di paren nel codice Perl agirà come raggruppamento di parenti o forma una lista?

Ad esempio, sono abbastanza sicuro che si tratta di un elenco scalare e non di un elemento: (1 + 1)
Ma per le espressioni più complesse? C'è un modo semplice per dirlo?

+0

Suppongo di essere principalmente preoccupato di assegnare accidentalmente un elenco di un elemento contenente un risultato anziché il risultato stesso a uno scalare. Ma se sto leggendo le risposte correttamente, questo è effettivamente impossibile, a meno che non faccia qualcosa come '$ x = @ {[1 + 1]};'. Sembra che assegnare un elenco a uno scalare sia diverso dall'assegnare un array a uno scalare. Cosa succede se assegni un elenco contenente un array a uno scalare? '$ x = (@list);' –

+0

In un compito, il lato sinistro determina il contesto in cui verrà valutato il lato destro. Pertanto, quando si assegna una matrice a una variabile scalare, la matrice viene valutata in un contesto scalare. Un array valutato in contesto scalare restituisce il numero di elementi nell'array. Entrambi gli esempi nel tuo commento rientrano in quella categoria. Notare anche che qui stiamo parlando della valutazione di un array in contesto scalare. Non stiamo parlando di un elenco in un contesto scalare, perché non ci sono elenchi in un contesto scalare. – FMc

+0

Immagino di aver sempre pensato che liste e array fossero sostanzialmente equivalenti e intercambiabili, ma non lo sono. –

risposta

16

Tre principi chiave sono utili qui:

contesto è re. La valutazione dell'esempio (1 + 1) dipende dal contesto.

$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. 

In un contesto scalare, non c'è cosa come un elenco. Per vedere questo, prova ad assegnare quello che appare a per essere una lista di una variabile scalare. Il modo di pensare a questo è di focalizzarsi sul comportamento dell'operatore virgola: in contesto scalare valuta il suo argomento di sinistra, getta via quel valore, quindi valuta il suo argomento giusto e restituisce quel valore. Nel contesto dell'elenco, l'operatore virgola inserisce entrambi gli argomenti nell'elenco.

@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. 

parentesi non creano liste. L'operatore virgola crea l'elenco (purché siamo nel contesto dell'elenco). Quando si digitano gli elenchi in codice Perl, le parentesi sono necessarie per motivi di precedenza, non per ragioni di creazione di elenchi. Alcuni esempi:

  • Le parentesi non hanno effetto: stiamo valutando un array di scalari contesto, in modo che il lato destro restituisce la dimensione della matrice.

    $x = (@arr); 
    
  • parentesi non sono necessari per creare una lista con un solo elemento.

    @arr = 33;   # Works fine, with @arr equal to (33). 
    
  • Ma parentesi sono necessari con più elementi - per motivi di precedenza.

    @arr = 12, 34, 56; # @arr equals (12). And we get warnings about using 
            # 34 and 56 in void context. 
    
8
  1. Contesto.
  2. Le parentesi non hanno il ruolo che si pensa di avere nella creazione di un elenco.

Esempi:

$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). 

In parole povere, nel contesto di lista l'operatore virgola separa gli elementi di una lista; in contesto scalare l'operatore virgola è la "virgola seriale" C, che valuta i suoi lati sinistro e destro e restituisce il valore del lato destro. Nel contesto scalare, le parentesi raggruppano le espressioni per sovrascrivere l'ordine delle operazioni e, nel contesto dell'elenco, le parentesi fanno ... la stessa identica cosa, davvero.La ragione per cui sono pertinenti nell'assegnare ad array è questo:

# 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); 

quanto riguarda la tua domanda "è uno scalare o un elenco di un elemento", non è solo una questione significativa per chiedere di un'espressione in isolamento , a causa del contesto. Nel contesto dell'elenco, tutto è una lista; in contesto scalare, nulla è.

Testi di: perlop, perldata, Programming Perl.

+0

Mi piace Deparse per mostrare l'operatore virgola: perl -MO = Deparse -le 'my @s = 1,3,4; print "@s" ' BEGIN {$/= "\ n"; $ \ = "\ n"; } my (@s) = 1, '???', '???'; stampa "@s"; -e sintassi OK –

Problemi correlati