next up previous contents
Next: Changing the Destination of Up: Basic I/O Previous: More Magic from the   Contents

The IO Module: Wave of the Future?

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.


next up previous contents
Next: Changing the Destination of Up: Basic I/O Previous: More Magic from the   Contents
Phil Spector 2002-10-18