"Perl for Perl Newbies" - Part 5 - Good Programming PracticesUseful Features in Recent PerlsLexical Filehandles

5.2. Lexical Filehandles

Traditionally Perl filehandles had been "typeglobs" - global names - normally starting with an uppercase letter that were not scope safe. While they could have been localised using "local", this was still a far cry from true lexical scoping. perl-5.6.x, however, introduced lexical filehandles for both file handles and directory handles.

Here is an example for a program implementing a directory listing.

#!/usr/bin/perl

use strict;
use warnings;

sub get_entries
{
    my $dir_path = shift;

    opendir my $dir_handle, $dir_path
        or die "Cannot open '$dir_path' as a directory - $!.";

    my @entries = readdir($dir_handle);

    closedir($dir_handle);

    return [ sort { $a cmp $b } @entries ];
}

foreach my $arg (@ARGV)
{
    print "== Listing for $arg ==\n";
    foreach my $entry (@{get_entries($arg)})
    {
        print $entry, "\n";
    }
}

And here is an example that copies a file:

#!/usr/bin/perl

# This is just for demonstration. A better way would be to use File::Copy :
#
# http://perldoc.perl.org/File/Copy.html
#

use strict;
use warnings;

my $source_fn = shift(@ARGV);
my $dest_fn = shift(@ARGV);

if ( (!defined($source_fn)) || (!defined($dest_fn)) )
{
    die "You must specify two arguments - source and destination."
}

open my $source_handle, "<", $source_fn
    or die "Could not open '$source_fn' - $!.";
open my $dest_handle, ">", $dest_fn
    or die "Could not open '$dest_fn' - $!.";

while (my $line = <$source_handle>)
{
    print {$dest_handle} $line;
}

close($source_handle);
close($dest_handle);

IO::Handle and Friends

Perl provides a set of lexical and object-oriented abstractions for file handles called IO::Handle. Starting from recent versions of Perl, one can use them with the built-in perlfunc mechanisms. You can find more information about them here:


Written by Shlomi Fish