The fact that filehandles don't begin with a special symbol is not the only thing that makes them different from other objects in perl. One very important difference is that it's awkward to pass a filehandle to a subroutine. Another is that filehandles can't easily be stored in arrays, since the perl interpreter mistakes them for ordinary barewords. For these reasons, a special module was added to perl to allow you to open files in a more ``traditional'' way, returning a perl variable (actually a reference), which can be used exactly like a filehandle, but behaves like a regular perl variable when passed to subroutines, or stored in an array.
If your programs don't expose the limitations of ordinary filehandles, there's no reason why you shouldn't use them. However some perl programmers feel that the IO module's method of opening files and pipes will eventually become the default behavior of perl, and that the old-style filehandles may eventually be deprecated. Because of this, and since the IO module's method does offer some useful capabilities which are difficult to achieve otherwise, it provides a good choice for introducing the idea of modules.
Actually, we've seen modules before, for example in Section 2.5, the
English module was introduced briefly. The English module simply
creates some variable aliases to allow you to refer to system variables in a more
convenient way; it didn't introduce any functions to extend perl's capabilities.
You incorporate a module in your perl program by using the use keyword.
Many modules are provided in a hierarchical structure. For example, the IO
module contains sub-modules for pipes and sockets as well as for files. In this
section, we'll use the IO::File module as an alternative to creating
old-style filehandles when we open a file. The double colons (::) are
used to specify the levels of hierarchy when referring to a module, and should not
be used as part of regular variable names.
Before continuing, it's once again worth mentioning the perldoc command.
You can get detailed information about any module in perl by typing perldoc
followed by the name of the module, including the full double-colon separated
hierarchy if it exists. So to get more information about the IO::File
module, simply type
perldoc IO::File
at the shell prompt. On properly configured UNIX systems, you should
also be able to access module's documentation through the man command.
There are two main routes through which modules add functionality to perl. First,
they may export the names of variables and/or functions to the local namespace,
allowing you to refer to these variables or functions just as if they were built
in to perl itself. The English module does this, since, once we have
accessed the module with the use statement, we don't need to remind perl
that, say, $OUTPUT_RECORD_SEPARATOR came from the English module;
the variable has been installed in the local namespace, and can be referred to
directly by name.
The other way that modules work is by providing a definition of a particular type
of object and providing methods (functions) which know how to operate on these
objects. In this case, you must first create a new object of the appropriate type
by telling perl exactly which module contains the necessary information to create
the object. Then, you use a special syntax on this newly created object to
invoke the methods you need. The general name for this type of programming is
object oriented programming. Don't worry if you don't understand all the implications
of these techniques; the information provided by the perldoc command should
be enough to get you started with most modules.
Let's look at how we can use the IO::File module as an alternative to
old-style filehandles. First, we must use the new operator to create
an IO::File object. The new operator provides what are known as
constructors for many of the objects defined in perl modules. You can use the
new operator without any arguments, but many modules allow you to provide
arguments. In the case of the IO::File object, any arguments you pass to
the new operator are automatically passed to the IO::File's
open method. The open method takes either a single argument, as
shown in Table
, or it can be provided with the filename and a
second argument representing the mode with which to open the file ('r' for
read, 'w' for write, or 'a' for append).
The perl syntax for invoking a method on an object uses the ``arrow'' operator,
composed of a dash and a greater than sign (->); you give the name of
the object, followed by the arrow operator, followed by the method call.
Like the ordinary open function, the open method of the IO::File
object will return the value undef if it fails to open a file, so the
construction described in Section
should still be used.
Once you open a file in
this way, the returned value can be used anywhere that an old-style filehandle
could be used.
To illustrate, we'll rewrite the example of Section
, using the
IO::File module. Since we're going to use the filehandle repeatedly,
the constructor is called without any arguments, and the open method
is repeatedly invoked.
use IO::File;
$fh = new IO::File;
while(<*.html>){
$fh->open("<$_") || die "Couldn't open $_";
$file = $_;
$maxlen = 0;
while(<$fh>){
$maxlen = length if length > $maxlen;
}
$fh->close();
print "$file: $maxlen\n";
}
The close method is not necessarily needed in this program, since perl
will automatically close a previously opened file if the open method is
reinvoked on a IO::File object. Furthermore, setting $fh to
undef would also close the file.