Usando il mio con parentesi e solo una variabile

A volte vedo il codice Perl in questo modo:

my ( $variable ) = blah.... 

Che senso ha mettere le parentesi attorno a una singola variabile? Pensavo che le parentesi fossero usate solo quando dichiari variabili multiple, come:

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

Ci sono diversi scenari in cui c’è una differenza:

  1. Quando la 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/ abcd /; # 'd' last item of the list my ($variable) = qw/ abcd /; # 'a' first item of the list 
  3. Subroutine con valore di ritorno variabile ( array / scalare )

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

Le parentesi creano un contesto di lista che influisce sul modo in cui viene valutata la parte destra del compito.

Confrontare

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

con

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

Userai spesso questa costruzione quando vuoi solo prendere il primo elemento di una lista e scartare il resto .

Non sono un professionista Perl (con tutti i mezzi, non lo sono), ma AFAIK ha a che fare con le liste. Perl ha diversi contesti (scalare, lista). Usando ($var) passa al contesto dell’elenco, $var è il contesto scalare.

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

Si prega di votare meno questa risposta, se è completamente sbagliato 🙂

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

 my $foo, $bar; 

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

 my $foo; $bar; 

Quindi hai bisogno di parentesi per raggruppare l’argomento in una lista di argomenti alla funzione my :

 my($foo, $bar); 

In secondo luogo, hai un raggruppamento esplicito per richiamare il contesto dell’elenco:

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

Saranno considerati tre dichiarazioni separate:

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

Ma se si usano le parentesi per raggruppare $foo e $bar in un elenco, l’operatore di assegnazione utilizzerà un contesto di lista:

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

Curiosamente, se si rimuovono le parentesi RHS, si verificherà anche un hickup:

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

Questo perché l’operatore = ha una precedenza più alta della virgola, che puoi vedere in perlop . Se provi:

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

Otterrai il comportamento desiderato senza parentesi.

Ora per completare il cerchio, rimuoviamo il contesto dell’elenco in alto e vediamo cosa succede:

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

Questo stampa 2 , poiché la matrice viene valutata in un contesto scalare e le matrici in contesto scalare restituiscono il numero di elementi che contengono. In questo caso, è 2 .

Quindi, dichiarazioni come queste usano il contesto dell’elenco:

 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 per sovrascrivere il contesto scalare implicito nell’assegnazione scalare. Per confronto, questi incarichi 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 

Ho pubblicato una spiegazione approfondita sull’argomento su 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.]