2013-05-28 16 views
6

Ho guardato incredulo questa sequenza:elenchi di argomenti di subroutine perl - "passa per alias"?

my $line; 
$rc = getline($line); # read next line and store in $line 

avevo capito da sempre che argomenti Perl stati passati per valore, quindi, quando ho bisogno di passare una grande struttura, oppure passare una variabile essere aggiornato, ho passato un riferimento.

Leggere la stampa fine in perldoc, tuttavia, ho appreso che @_ è composto da alias per le variabili menzionate nell'elenco degli argomenti. Dopo aver letto il prossimo bit di dati, getline() lo restituisce con $ _ [0] = $ dati;, che memorizza $ data direttamente in $ linea.

Mi piace così: è come passare per riferimento in C++. Tuttavia, non ho trovato un modo per assegnare un nome più significativo a $ _ [0]. C'è qualche?

+0

sì, Perl è sempre pass-per-riferimento – newacct

+0

Bene - non deve essere confuso con i riferimenti Perl, che sono più come i puntatori C in quanto devono essere esplicitamente dereferenziati. – Chap

+0

non $ arg = shift; $ arg = $ dati; fallo? O cambierà invece una copia dell'argomento? EDIT: Ho testato gli indirizzi di uno scalare passato e l'argomento 'shift', ed i risultati dicono che il turno fa una copia, quindi assegnare $ arg come sopra non influenzerà $ line come previsto. :( – sundar

risposta

7

È possibile, la sua non è molto carina:

use strict; 
use warnings; 

sub inc { 
    # manipulate the local symbol table 
    # to refer to the alias by $name 
    our $name; local *name = \$_[0]; 

    # $name is an alias to first argument 
    $name++; 
} 

my $x = 1; 
inc($x); 
print $x; # 2 
+1

È disponibile una considerevole prettificazione da 'Data :: Alias'. – darch

+0

, Method :: Signatures ha un [alias trait] (https://metacpan.org/module/Method::Signatures#Parameter-traits) –

0

Il modo più semplice è probabilmente solo per utilizzare un ciclo, dal momento che i cicli alias i loro argomenti a un nome; vale a dire

sub my_sub { 
    for my $arg ($_[0]) { 
    code here sees $arg as an alias for $_[0] 
    } 
} 
+0

Vero, ma non proprio quello che stavo cercando - idealmente avrei voluto dare nomi distinti a ciascun argomento: sembra che Joel lo faccia, ma come dice lui è piuttosto caotico – Chap

+0

@Chap: ho aggiunto una risposta http://stackoverflow.com/a/17343595/8127 che consente nomi distinti per ogni argomento, ma anche questo è disordinato a modo suo. – sundar

0

Una versione di @ codice di Steve che permette più argomenti distinti:

sub my_sub { 
    SUB: 
    for my $thisarg ($_[0]) { 
    for my $thatarg ($_[1]) { 
     code here sees $thisarg and $thatarg as aliases 
     last SUB; 
    } 
    } 
} 

Naturalmente questo porta nesting multilivello e propri problemi di leggibilità del codice, in modo da utilizzare solo quando assolutamente necessario.