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::Fileat 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.