2012-04-05 7 views
29

volte vedo codice Perl in questo modo:Usando il mio con parentesi e una sola variabile

my ($variable) = blah.... 

Qual è il punto di mettere parentesi intorno ad una singola variabile? Ho pensato parentesi sono stati utilizzati solo quando si dichiara più variabili, come:

my ($var1, $var2, $var3) = blah... 
+2

potrebbe essere utile per la manutenzione, se è evidente che una lista potrebbe essere l'aspettativa futura. Normalmente lo uso durante la lettura degli argomenti di subroutine, come 'my ($ arg1) = @ _' piuttosto che' my $ arg1 = shift' – Unos

+0

Sono abituato a digitare 'my ('. E, una lista di un elemento è ancora una lista. :) –

risposta

34

Ci sono diversi scenari quando v'è una differenza:

  1. Quando matrice è sul lato destro

    my @array = ('a', 'b', 'c'); 
    my $variable = @array;   # 3 size of @array 
    my ($variable) = @array;   # 'a' $array[0] 
    
  2. Quando la lista è sul lato destro

    my $variable = qw/ a b c d /; # 'd' last item of the list 
    my ($variable) = qw/ a b c d /; # 'a' first item of the list 
    
  3. SP con variabile (matrice/scalare) valore restituito

    sub myFunction { 
        ... 
        return (wantarray() ? @array : $scalar); 
    } 
    my $variable = myFunction(...); # $scalar from the subroutine 
    my ($variable) = myFunction(...); # $array[0] from the subroutine 
    
+1

Grazie, mi piace che tu abbia fornito diversi scenari. –

+1

@brian d foy, non capisco il tuo commento. Stai cercando di implicare che il termine "array" o "elenco" sia usato in modo errato in questo post? Perché non vedo alcun abuso. – ikegami

6

Io non sono un professionista Perl (con tutti i mezzi, io non sono), ma per quanto ne so ha a che fare con le liste. Perl ha contesti diversi (scalare, lista). L'utilizzo di ($var) passa al contesto dell'elenco, $var è un contesto scalare.

my $var = (1, 2, 4); # $var = 4 (last element) 
my ($var) = (1, 2, 4); # $var = 1 

Si prega di downvote questa risposta, se è del tutto sbagliato :)

+0

Hai ragione, e '$ var = grep {; definito} (1, 2, 4); '= 3 (articoli) – Axeman

+0

Anche' my @a = (1,2,4); my $ v = @a; print $ v; '= 3 – knittl

+0

Tuttavia' $ var = (1, 2, 4) 'assegna 4 a' $ var'. 'grep' si comporta in un modo specifico a seconda del suo contesto, e in contesto scalare fornisce il numero di elementi di lista che superano il test. Questo è diverso dal comportamento di un elenco in contesto scalare. – Borodin

18

Le parentesi creare un contesto di lista, che colpisce come il lato destro della cessione è valutata.

Confronta

my $x = grep { /s/ } qw(apples bananas cherries); 
print $x; 

con

my ($x) = grep { /s/ } qw(apples bananas cherries); 
print $x; 

spesso Si utilizzerà questo costruzione quando you just want to grab the first element of a list and discard the rest.

+0

Tecnicamente, influisce sul modo in cui vengono valutati entrambi i lati dell'operatore di assegnazione (modificando l'operatore di assegnazione utilizzato). – ikegami

+0

Grazie, ha senso. –

6

Stai confondendo due cose diverse. Prima di tutto, quando si utilizza my di dichiarare diverse variabili, è necessario utilizzare le parentesi:

my $foo, $bar; 

Non funziona, in quanto è considerato come due affermazioni diverse:

my $foo; 
$bar; 

quindi è necessario parentesi a raggruppare l'argomento in elenco argomento della funzione my:

my($foo, $bar); 

In secondo luogo, si ha il raggruppamento esplicito per invocare un contesto di lista:

$foo, $bar = "a", "b"; # wrong! 

saranno prese in considerazione tre prospetti separati:

$foo; 
$bar = "a"; 
"b"; 

Ma se si utilizza parentesi per raggruppare $foo e $bar in un elenco, il operatore di assegnazione userà un contesto di lista:

($foo, $bar) = ("a", "b"); 

Curiosamente, se si rimuove le parentesi RHS, sarà anche l'esperienza un hickup:

($foo, $bar) = "a", "b"; # Useless use of a constant (b) in void context 

ma è perché l'operatore = ha precedenza maggiore rispetto virgola ,, che potete vedere in perlop. Se si tenta:

my @array = ("a", "b"); 
($foo, $bar) = @array; 

Si otterrà il comportamento desiderato senza parentesi.

Ora per completare il cerchio, permette rimuovere il contesto di lista di cui sopra e vedere cosa succede:

my @array = ("a", "b"); 
$foo = @array; 
print $foo; 

Questo stampa 2, perché la matrice viene valutata in un contesto scalare, e gli array in un contesto scalare restituisce il numero di elementi che contengono In questo caso, è 2.

Pertanto, tali affermazioni contesto lista uso:

my ($foo) = @array;   # $foo is set to $array[0], first array element 
my ($bar) = ("a", "b", "c"); # $bar is set to "a", first list element 

è un modo di override contesto scalare che è implicato in assegnazione scalare. Per confronto, queste assegnazioni sono in contesto scalare:

my $foo = @array;   # $foo is set to the number of elements in the array 
my $bar = ("a", "b", "c"); # $bar is set to "c", last list element 
+0

Abbastanza interessante, 'my $ foo = (" a "," b "); stampa $ pippo; 'stampa' b', e non '2' – knittl

+0

@knittl Non così interessante come sembra, perché solo * array * hanno quel comportamento, non liste. Nel contesto scalare, gli elenchi restituiscono invece il loro ultimo elemento. – TLP

+1

[perlfaq4: Qual è la differenza tra un elenco e un array?] (Http://perldoc.perl.org/perlfaq4.html#What-is-the-difference- between between-a-list-and-an-array % 3f) –

2

ho postato un approfondito explanation sull'argomento in un altro sito.

[Non riesco a postarlo qui. StackOverflow non supporta tabelle. Non che qualcuno di solito abbia un problema con il collegamento fuori sito alla documentazione.]

+0

Perché il downvote? – ikegami

+1

Apparentemente qualcuno ha un problema con il collegamento fuori sito alla documentazione. Di solito raccomando di aggiungere un riassunto alla tua risposta. –

+0

@Brad Gilbert, ripetere ciò che è stato già detto 4 volte non è una buona cosa per quanto mi riguarda. – ikegami

Problemi correlati