Whenever I want to simulate input and output to a filehandle, I'll often use references to DATA
and STDOUT
respectively:
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
Outputs:
Hello World
However, in a recent answer by Borodin, it was demonstrated that it's not actually necessary to take a reference. Instead, a simple assignment is sufficient:
my $infh = *DATA;
I therefore created the following script to compare and contrast the difference between these two methods:
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
Outputs:
Name Value ref() readline()
\*DATA GLOB(0x7fdc43027e70) GLOB Hello World
*DATA *main::DATA Hello World
When it comes to passing and reading from the filehandle, there appears no difference between a typeglob and a reference to a typeglob.
Switching from testing to the research form of investigation reveals the following perldoc pages:
The first reference suggests either usage. While the second gives a list of other alternatives as well, but mentions how the reference notation is needed if we want to bless the variable. No other difference is suggested.
Is there a functional or preferred style difference these two indirect filehandles?
my $fh = \*DATA;
my $fh = *DATA;
One's a glob; one's a reference to a glob. Most places accept both. Many also accept the name of the glob as a string, and many accept a reference to an IO object.
# 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, '<', ...)
populates $fh
with a reference to a glob, and it's the most supported, so that's what I use if I have to choose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With