2010-10-29 13 views
7

In perldoc perlvar, ho letto questo:Come posso dire a una funzione Perl che prende un file da leggere dall'hand speciale ARGV?

Nota che attualmente "ARGV" ha solo suo effetto magico all'interno del "<>" dell'operatore; altrove è semplicemente un filehandle corrispondente all'ultimo file aperto da "<>". In particolare, passa "* ARGV" come parametro a una funzione che si aspetta che un filehandle possa non causa la lettura automatica del contenuto di tutti i file di in @ARGV.

Quindi, come si può I passare *ARGV (o qualcosa che assomiglia ad esso) come un paramter a una funzione che prevede un filehandle, e che hanno la funzione leggere tutti i file in @ARGV?

risposta

12

andare avanti a destra e passare il *ARGV typeglob o \*ARGV, il suo riferimento. Assicurati che la funzione alla fine lo faccia tramite l'operatore <$fh> o readline($fh), l'equivalente funzionale sottostante.

La questione affrontata nel passaggio citato dal perlvar sta solo cercando di ricordare che non sarà in grado di ottenere ARGV s' magia aperta per innescare se qualsiasi altro meccanismo di lettura utilizzo di readline sulla gestire, ad esempio read, sysread o getc.

Esegui questo per dimostrare a te stesso che funziona:

sub mycat { 
    my $fh = shift; 
    print "$ARGV $.: $_" while <$fh>; 
} 
mycat(*ARGV); 

Metti che in un file, quindi eseguirlo con diversi argomenti di file:

% perl mycat ./mycat //`pwd`/mycat ~/mycat 
./mycat 1: sub mycat { 
./mycat 2:  my $fh = shift; 
./mycat 3:  print "$ARGV $.: $_" while <$fh>; 
./mycat 4: } 
./mycat 5: mycat(*ARGV); 
///home/tchrist/mycat 6: sub mycat { 
///home/tchrist/mycat 7:  my $fh = shift; 
///home/tchrist/mycat 8:  print "$ARGV $.: $_" while <$fh>; 
///home/tchrist/mycat 9: } 
///home/tchrist/mycat 10: mycat(*ARGV); 
/home/tchrist/mycat 11: sub mycat { 
/home/tchrist/mycat 12:  my $fh = shift; 
/home/tchrist/mycat 13:  print "$ARGV $.: $_" while <$fh>; 
/home/tchrist/mycat 14: } 
/home/tchrist/mycat 15: mycat(*ARGV); 

Vedi? Funziona bene.

+1

Huh. Il mio programma ha iniziato a funzionare dopo aver letto questo. –

-1

Si potrebbe fingere con cat (su un sistema Unix)

open FAKE_ARGV, "cat @ARGV |"; 
function_expecting_filehandle(*FAKE_ARGV); 
... 

È perdere un po 'della magia ($ARGV, $.) con questo.

Sono sicuro che c'è anche modo di utilizzare un filehandle legato (vedere perltie).

1

È possibile siano rinviati <> quando l'iterazione di un oggetto sovraccarico:

{package ReadARGV; 
    sub new {bless []} 
    use overload '<>' => sub {<>}; 
} 

sub reader { 
    my $fh = shift; 
    local $_; 
    print while <$fh>; 
} 

reader(ReadARGV->new); 

Il pacchetto ReadARGV contiene un semplice costruttore dell'oggetto new e quindi sovraccarica l'operatore <HANDLE> di chiamare semplicemente <>.