2016-03-14 7 views
8

Per salvare 2 valori da una lista restituita da un sub e lanciare il terzo, si può;Perché l'assegnazione a un elenco di variabili è incoerente?

(my $first, my $second) = (1, 2, 3); 
print $first, "\n"; 
print $second, "\n"; 
exit 0; 

e funziona come previsto (in perl5 e perl6). Se vuoi solo il primo però;

(my $first) = (1, 2, 3); 
print $first, "\n"; 
exit 0; 

... si ottiene l'intera lista. Questo sembra contro-intuitivo - perché l'incoerenza?

risposta

9

Questo dovrebbe essere dovuto allo single argument rule. È possibile ottenere il comportamento previsto con l'aggiunta di un trailing ,:

(my $first,) = (1, 2, 3); 

Nota che, mentre questo funziona come le dichiarazioni restituire i contenitori, che sono oggetti di prima classe che possono essere messi in lista, si sta comunque facendo 'sbagliato' :

Le assegnazioni devono leggere

my ($first, $second) = (1, 2, 3); 

e

my ($first) = (1, 2, 3); 

Si noti inoltre che i parents sul lato destro sono superflui (è la virgola che elenca la costruzione); le versioni più idiomatiche sarebbero

my ($first, $second) = 1, 2, 3; 

e

my ($first) = 1, 2, 3; 
+0

non ho ben capito il motivo per cui il mio '($ prima) = 1,2,3'; * fa * funziona come previsto. Non dovrebbe valere anche il singolo argomento? In altre parole, come è diverso da '(my $ first) = 1,2,3;' o 'my $ prima; ($ prima) = 1,2,3; '? – mscha

+0

@mscha: i parenti sono sintatticamente sovraccaricati: sono usati come parte della sintassi delle dichiarazioni e delimitano liste ordinarie (che possono contenere oggetti che sono assegnabili); sintatticamente potrebbe sembrare simile, ma semanticamente, mele e arance – Christoph

+0

@mscha: per coerenza, sarebbe stata una buona idea rendere uguali le regole, ma notare che la semantica delle liste si è evoluta durante il piuttosto lungo processo di sviluppo di Perl6 – Christoph

6
(my $first,) = (1,2,3); 
dd $first; # OUTPUT«Int $first = 1␤» 

Nel vostro primo esempio si assegna un elenco (o una parte di esso) a un elenco di contenitori. Il tuo secondo esempio fa esattamente quello che gli chiedi. Un elenco di valori è assegnato a un contenitore. In Perl 5, la lista è costruita dalle parentesi (in questo caso), per cui in Perl 6 la lista è costruita con la virgola. Quest'ultimo è usato nel mio esempio per ottenere ciò che è richiesto.

Direi che è Perl 5 che è incoerente perché a volte le liste sono costruite con virgole, parentesi o parentesi.

my ($first,$,$third) = (1,2,3); 
dd $first, $third; # OUTPUT«Int $first = 1␤Int $third = 3␤» 

È possibile saltare uno o più elementi dell'elenco aggiungendo variabili di stato anonime. Questo porta anche a un collegamento al tuo primo esempio.

my $first,$ = 1,2,3; 
dd $first; # OUTPUT«Any $first = Any␤» 
Problemi correlati