"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, introducedlexical 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