-+  Associazione
-+  Documenti
 |-  Modern Perl
 |-  Bibliografia
 |-  Articoli
 |-  Talk
 |-  Perlfunc
 |-  F.A.Q.
 |-  F.A.Q. iclp
-+  Eventi
-+  Community
-+  Blog
-+  Link
Corso di Perl



 


indietro

[9] Come posso utilizzare un filehandle in maniera indiretta? filehandle, indiretta

Utilizzare un filehandle in maniera indiretta significa usare qualcosa di diverso da un simbolo in un luogo dove è richiesto un filehandle Di seguito sono riportati alcuni modi per ottenere un filehandle indiretto:

    $fh =   UN_FH;       # parola senza virgolette; E<egrave> ostile a stict subs
    $fh =  "UN_FH";      # E<egrave> ostile a strict-refs; solo nello stesso package
    $fh =  *UN_FH;       # typeglob
    $fh = \*UN_FH;       # reference ad un typeglob (bless-abile)
    $fh =  *UN_FH{IO};   # IO::Handle blessed dal typeglob *UN_FH

Oppure potete servirvi del metodo new da uno dei moduli IO::* per creare un filehandle anonimo, memorizzarlo in una variabile scalare, ed utilizzarlo come se fosse un normale filehandle.

    use IO::Handle;                     # 5.004 o superiore
    $fh = IO::Handle->new();

Usate poi uno di quelli come fareste con un normale filehandle. Ovunque Perl si aspetti un filehandle, al suo posto può essere utilizzato un filehanle indiretto. Un filehandle indiretto è semplicemente una variabile scalare che contiene un filehandle. Funzioni quali print, open, seek, o l'operatore <FH> accetteranno sia un filehandle vero e proprio che una variabile scalare che ne contenga uno:

    ($ifh, $ofh, $efh) = (*STDIN, *STDOUT, *STDERR);
    print $ofh "Scrivilo: ";
    $ottenuto = <$ifh>;
    print $efh "Cos'era quello: $ottenuto";

Se state passando un filehandle ad una funzione, potete scrivere tale funzione in due modi:

    sub accetta_fh {
        my $fh = shift;
        print $fh "Sto inviando ad un filehandle indiretto\n";
    }

Oppure potete localizzare un typeglob ed utilizzare direttamente il filehandle:

    sub accetta_fh {
        local *FH = shift;
        print  FH "Sto inviando ad un filehandle localizzato\n";
    }

Entrambi gli stili funzionano sia con oggetti che con typeglob che con filehandle reali. (Potrebbero anche funzionare con stringhe in alcune circostanze, ma la cosa è rischiosa.)

    accept_fh(*STDOUT);
    accept_fh($handle);

Negli esempi sopra riportati, abbiamo assegnato il filehandle ad una variabile scalare prima di utilizzarlo. Ciò accade perché solo le semplici variabili scalari, e non espressioni o elementi di hash oppure array, possono essere usati con le funzioni integrate come print e printf, o con l'operatore diamante [<FH>, NdT]. L'utilizzo di qualcosa di diverso da una semplice variabile scalare come filehandle non è consentito, ed il programma non compilerà nemmeno:

    @fd = (*STDIN, *STDOUT, *STDERR);
    print $fd[1] "Scrivilo: ";                          # ERRATO
    $ottenuto = <$fd[0]>;                               # ERRATO
    print $fd[2] "Cos'era quello: $ottenuto";           # ERRATO

Con print e printf potete aggirare ciò servendovi di un blocco ed un'espressione al posto del filehandle:

    print  { $fd[1] } "cose carine\n";
    printf { $fd[1] } "Peccato per la povera %x.\n", 3_735_928_559;
    # Peccato per la povera deadbeef. [convenzionalmente, uno schema esadecimale utilizzato per riempire parole di memoria, NdT]

Questo blocco è un blocco valido come qualsiasi altro, quindi potete inserire codice più complesso al suo interno. Il codice di seguito riportato invia il messaggio in uno dei due posti:

    $ok = -x "/bin/cat";
    print { $ok ? $fd[1] : $fd[2] } "cat stat $ok\n";
    print { $fd[ 1+ ($ok || 0) ]  } "cat stat $ok\n";

Questo approccio, consistente nel trattare print e printf come chiamate a metodi di un oggetto, non funziona con l'operatore diamante. Ciò accade perché esso è un vero operatore, non solo una funzione con argomenti non separati da virgola. Ponendo che abbiate memorizzato i tyeglob nella vostra struttura come indicato in precedenza, potete utilizzare la funzione integrata readline per leggere un record allo stesso modo in cui fa <>. Posta l'inizializzazione indicata prima per @fd, ciò dovrebbe funzionare, ma solo perché readline() richiede un typeglob. Non funziona con oggetti o stringhe, il che potrebbe essere un bug che non abbiamo ancora corretto.

    $ottenuto = readline($fd[0]);

Va notato che la debolezza dei filehandle indiretti non è collegata al fatto che essi siano stringhe, typeglob, oggetti, o qualsiasi altra cosa. è la sintassi degli operatori fondamentali. Il gioco degli oggetti non vi è di alcun aiuto qui.

vedi in inglese

AUTORE E COPYRIGHT

Copyright (c) 1997, 1998, 1999, 2000, 2001 Tom Christiansen e Nathan Torkington. Tutti i diritti riservati.

Questa documentazione è libera; puoi ridistribuirla e/o modificarla secondo gli stessi termini applicati al Perl.

Indipendentemente dalle modalitè di distribuzione, tutti gli esempi di codice in questo file sono rilasciati al pubblico dominio. Potete, e siete incoraggiati a farlo, utilizzare il presente codice o qualunque forma derivata da esso nei vostri programmi per divertimento o per profitto. Un semplice commento nel codice che dia riconoscimento alle FAQ sarebbe cortese ma non è obbligatorio.

D:
Progetti e documenti in rilievo
Corso di Perl Progetto pod2it
D:
La ML di Perl.it
mongers@perl.it è la lista ufficiale di Perl Mongers Italia per porre quesiti di tipo tecnico, per rimanere aggiornato su meeting, incontri, manifestazioni e novità su Perl.it.
Iscriviti!
D:
Annunci Google