home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Perl CookbookPerl CookbookSearch this book

7.13. Storing Multiple Files in the DATA Area

7.13.1. Problem

You've figured out how to use _ _END_ _ or _ _DATA_ _ to store a virtual file in your source code, but you now want multiple virtual files in one source file.

7.13.2. Solution

Use the Inline::Files module from CPAN. Carefully.

use Inline::Files;

while (<SETUP>) {
  # ...
}

while (<EXECUTION>) {
  # ...
}

_ _SETUP_ _
everything for the SETUP filehandle goes here
_ _EXECUTION_ _
everything for the EXECUTION filehandle goes here

7.13.3. Discussion

One limitation with the _ _DATA_ _ setup is that you can have only one embedded data file per physical file. The CPAN module Inline::Files cleverly circumvents this restriction by providing logical embedded files. It's used like this:

use Inline::Files;

#
#  All your code for the file goes here first, then...
#

_ _ALPHA_ _
This is the data in the first virtual file, ALPHA.

_ _BETA_ _
This is the data in the next virtual file, BETA.

_ _OMEGA_ _
This is the data in yet another virtual file, OMEGA.

_ _ALPHA_ _
This is more data in the second part of virtual file, ALPHA.

The code is expected to read from filehandles whose names correspond to the double-underbarred symbols: here ALPHA, BETA, and OMEGA. You may have more than one section by the same name in the same program, and differently named sections needn't be read in any particular order. These handles work much like the ARGV handle does. For one thing, they're implicitly opened on first usage. For example, using the following code in the designated spot in the preceding code example:

while (<OMEGA>) {
   print "omega data: $_";
}

while (<ALPHA>) {
   print "alpha data: $_";
}

would produce this:

omega data: This is the data in yet another virtual file, OMEGA.
omega data:
alpha data: This is the data in the first virtual file, ALPHA.
alpha data:
alpha data: This is more data in the second part of virtual file, ALPHA.
alpha data:

Also like the ARGV handle, while reading from a particular handle, the list of available virtual files is in the array by that name, and the currently opened virtual file is in the scalar by that name. There's also a hash by that name that holds various bits of status information about that set of virtual files, including the current file, line number, and byte offset. If we used the Perl debugger on this program and dumped out the variables, it might show this:

DB2> \$ALPHA, \@ALPHA, \%ALPHA
0  SCALAR(0x362e34)
   -> '/home/tchrist/inline-demo(00000000000000000291)'
1  ARRAY(0x362e40)
   0  '/home/tchrist/inline-demo(00000000000000000291)'
   1  '/home/tchrist/inline-demo(00000000000000000476)'
2  HASH(0x362edc)
   'file' => undef
   'line' => undef
   'offset' => undef
   'writable' => 1

What's that last line telling us? It tells whether that virtual file is writable. By default, if your script is writable, then so too are the virtual files, and they are opened in read-write mode! Yes, that means you can update them yourself, including even adding new virtual files to your source code simply by running that code. There is absolutely no limit to the mischief or grief that can ensue from this: catastrophes are easy to come by as you accidentally obliterate your painstakingly won data. We therefore implore you to back everything up first. The module itself supports an automatic mechanism for this:

use Inline::Files -backup;

which saves the original in a file with a ".bak" appended to it. You may also specify an explicit backup file:

use Inline::Files -backup => "/tmp/safety_net";


Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.