2013-06-07 10 views
13

Devo apportare modifiche a uno script Perl e questo è il mio primo tentativo di comprendere Perl. Vedo il seguente:Sintassi Perl insolita

my %trades; 
... 
foreach my $row (@$rows) { 
    @{$trades{pop @$row}} = @$row; 
} 

Sono confuso da questo perché sembra che ci stanno spuntando fuori l'ultimo elemento dell'array @$row e impostando il tasto cancelletto di %trades essere l'elemento che è stato spuntato fuori e l'impostazione del valore da @$row.

Questa comprensione è corretta?

+10

Solo una nota di stile: tipicamente "Perl" per la lingua e "perl" per il programma. Non è "PERL" a meno che il tuo tasto Maiusc sia bloccato. :) – cHao

+0

Potrebbe anche essere scritto '$ trades {pop @ $ row} = $ row;' o 'my $ id = pop @ $ row; $ trades {$ id} = $ row; ' – ikegami

+0

@ikegami: No. Perché il tuo copia riferimenti mentre l'originale copia gli elementi dell'array. – Borodin

risposta

26

capire che pezzo di codice, dobbiamo essere chiari su tre cose: ordine

  • Valutazione:

    EXPR_A = EXPR_B 
    

    valuta le EXPR_B prima di valutare EXPR_A.

  • semantica di copia:

    @new_array = @old_array 
    

    copia i valori di @old_array oltre a @new_array.

  • Dereferencing di strutture dati complesse:

    @{ $trades{$key} } 
    

    accede dall'entrata chiamato $key nel %trades hash, che è considerata come un riferimento di matrice.

Insieme, il codice è equivalente a questo:

foreach my $row (@$rows) { 
    my @copy = @$row; 
    my $key = pop @$row; 
    @{ $trades{$key} } = @copy; 
} 

(pur conservando tutti gli effetti collaterali che posso vedere)

Così, per esempio

$rows = [ 
    [1, 2, "keyA"], 
    [3, 4, "keyB"], 
]; 

creerebbe

%trades = (
    keyA => [1, 2, "keyA"], 
    keyB => [3, 4, "keyB"], 
); 
$rows = [ 
    [1, 2], 
    [3, 4], 
]; 

Chiunque abbia scritto quella riga aveva una conoscenza molto precisa dell'ordine di valutazione e ama torturare i programmatori di manutenzione.

+2

in particolare, sembra riempire '% trades' con una copia di ogni riga da' @ rows', dove la chiave per ogni voce è il valore dell'ultima colonna di quella riga. – Alnitak

+0

Avrei +1000 per te se potessi per il tuo ultimo commento da solo. – czchlong

+6

Chiunque abbia scritto quel codice può conoscere Perl, ma non sa molto sulle buone pratiche di sviluppo del software. E una delle moltitudini di idioti che hanno dato a Perl una così terribile reputazione che la maggior parte delle aziende si rifiuta di usarlo. – DVK

3

Il ciclo è equivalente a

my %trades = map { $_->[-1] => [ @$_ ] } @$rows 

tranne che in questo modo @$rows rimane non modificato. IMO dovrebbe essere scritto in questo modo.

+0

Tranne l'ultimo elemento per ogni riga in $ righe è perso nel codice originale. –

Problemi correlati