2014-09-10 20 views
7

Ogni volta che voglio simulare input e output ad un filehandle, io uso spesso riferimenti a DATA e STDOUT rispettivamente:Differenza tra * DATA e * DATI

use strict; 
use warnings; 
use autodie; 

#open my $infh, '<', 'infile.txt'; 
my $infh = \*DATA; 

#open my $outfh, '>', 'outfile.txt'; 
my $outfh, \*STDOUT; 

print $outfh <$infh>; 

__DATA__ 
Hello World 

Uscite:

Hello World 

Tuttavia, in un recent answer di Borodin, è stato dimostrato che in realtà non è necessario prendere un riferimento. Invece, un'assegnazione semplice è sufficiente:

my $infh = *DATA; 

pertanto creato il seguente script a confrontare la differenza tra questi due metodi:

use strict; 
use warnings; 

use Fcntl qw(:seek); 

# Compare Indirect Filehandle Notation 
my %hash = (
    '\*DATA' => \*DATA, 
    '*DATA' => *DATA, 
); 

my $pos = tell DATA; 

my $fmt = "%-8s %-22s %-7s %s\n"; 
printf $fmt, qw(Name Value ref() readline()); 

while (my ($name, $fh) = each %hash) { 
    seek($fh, $pos, SEEK_SET); # Rewind FH 
    chomp(my $line = <$fh>); 
    printf $fmt, $name, $fh, ref($fh), $line; 
} 

__DATA__ 
Hello World 

Uscite:

Name  Value     ref() readline() 
\*DATA GLOB(0x7fdc43027e70) GLOB Hello World 
*DATA *main::DATA     Hello World 

Quando viene a passare e leggere dal filehandle, non appare alcuna differenza tra un typeglob e un riferimento a un typeglob.

passaggio da test per la forma di ricerca di ricerca rivela seguenti pagine perldoc:

Il primo riferimento suggerisce o utilizzo. Mentre il secondo fornisce una lista di altre alternative, ma menziona come la notazione di riferimento è necessaria se vogliamo benedire la variabile. Non viene suggerita alcuna altra differenza.

C'è una differenza di stile funzionale o preferita questi due filehandle indiretti?

  1. my $fh = \*DATA;
  2. my $fh = *DATA;
+2

La mia reazione immediata è che ogni personaggio in più aggiunge quel po 'di potenziale in più per la confusione da qualche parte lungo la strada ... – abiessu

+0

molti posti accettano anche un ioref ('* DATA {IO}') – ysth

+2

@abiessu, direi che essere incoerente con ciò che apre i miei ritorni $ fh è in realtà più probabile che causi confusione. – ikegami

risposta

9

Uno è un glob; uno è un riferimento a un glob. La maggior parte dei posti accetta entrambi. Molti accettano anche il nome del glob come stringa e molti accettano un riferimento a un oggetto IO.

# Symbolic reference to the glob that contains the IO object. 
>perl -E"$fh = 'STDOUT'; say $fh 'hi'" 
hi 

# Reference to the glob that contains the IO object. 
>perl -E"$fh = \*STDOUT; say $fh 'hi'" 
hi 

# Glob that contains the IO object. 
>perl -E"$fh = *STDOUT;  say $fh 'hi'" 
hi 

# Reference to the IO object. 
>perl -E"$fh = *STDOUT{IO}; say $fh 'hi'" 
hi 

open(my $fh, '<', ...) popola $fh con un riferimento a un glob, ed è il più sostenuto, ed è quello che io uso se devo scegliere.

+0

Sono contento di sapere che non ci sono problemi funzionali di cui preoccuparsi. Il tuo ultimo punto sul mirroring di 'open my $ fh' è molto utile dal punto di vista dello stile. Inoltre, poiché la maggior parte delle volte sto provando a modellare il codice per i principianti, è probabilmente anche utile dimostrare di usare riferimenti poiché non dobbiamo confonderli con un'eccezione alla regola su come passare strutture di dati complesse. – Miller

Problemi correlati