modulereview
ariels
Damian Conway
code filter
Inline
Conway
Damian
Another of the (good) <a href="http://www.yetanother.org/damian/">Dr. Damian Conway</a>'s
modules, <tt>[cpan://Inline::Files]</tt> is another <i>tour de force</i> of
Perl source code filtering, symbol table manipulation, overridden
builtins and a wholly outlandish yet useful concept, wrapped in
an entirely Perlish syntax.
</p>
<p>
(In case you're wondering, yes, I like the module)
</p>
<h3>A word of warning!</h3>
<p>
If you're a "hands-on" person, you might want to install and use
this module before finishing to read the documentation or this
review. <em>PLEASE</em> be careful, and use the <tt>-backup</tt>
flag to the module, <em>at least</em> until you understand what it
does! Say "<code>use Inline::Files -backup</code>" instead of
"<code>use Inline::Files</code>"!
</p>
<h3>What does it do?</h3>
<p>
Ever needed to package a few small files along with your program?
Well, you can use <tt>[DATA]</tt>. But that just gives you one
"file". And it's always on the <tt>DATA</tt> filehandle, which
might not suit your programming style.
</p>
<p>
Or you can use the "here-document" syntax to get at some strings
in your program. That gives you as many strings as you like, but
you can't use file operators to read them. And changing them can
be tricky (see below for just how easy <tt>Inline::Files</tt>
makes it to <em>change</em> your files...).
</p>
<p>
<tt>Inline::Files</tt> lets you read "virtual files" which you
enclose in your program's source. At <tt>[BEGIN]</tt> time it
does its magic, and you have some new files available to you.
</p>
<h3>Virtual files</h3>
<p>
At the end of your program, you can put any number of what
<tt>Inline::Files</tt> calls <em>virtual files</em>. These are
just regions of you text beginning with special markers
<tt>__<i>YOUR_CHOICE_OF_ID</i>__</tt>. You can then read the
contents of this "virtual file" by reading the [filehandle]
<tt><<i>YOUR_CHOICE_OF_ID</i>></tt>. Note that
<tt><i>YOUR_CHOICE_OF_ID</i></tt> is the name of a filehandle, so
it should be in UPPER CASE, or it won't be recognised.
</p>
<p>
More than one virtual file can be associated with the same ID;
reading from the filehandle will retrieve them in order.
</p>
<p>
More information is available about these virtual files. In
particular, you can get a list of the "virtual file
<em>names</em>" associated with each ID; <tt>[open]</tt> is
overloaded to know how to open these files by their names. You
can also get the name of the current file being read by the ID, as
well as some more esoteric information.
</p>
<h4>An example</h4>
<p>
<blockquote><code>
#!/usr/local/bin/perl -w
use Inline::Files;
my ($a,$b,$a_end,$b_end);
for($a=<A>, $b=<B>;
! $a_end || ! $b_end;
($a_end or $a=<A>), ($b_end or $b=<B>)) {
$a_end=1, $a='' unless defined $a;
$b_end=1, $b='' unless defined $b;
chomp($a);
chomp($b);
printf "%35s | %35s\n", $a, $b;
}
__A__
This is a block of text.
Note that this text had best
have *SHORT* lines, or we
could have some formatting
trouble!
__B__
The quick brown fox jumps
over the lazy dog. The cow
jumps over the moon.
</code></blockquote>
This code arranges 2 blocks of text in a nice manner; the text is
read directly from a virtual file, which is nicer than having to
split on all newlines of a string.
</p>
<p>
It's also a nice way to test some code you want to write to run on
real filehandles, while keeping everything in one file.
</p>
<h3>Writing</h3>
<p>
Not content with letting your programs read parts of themselves in
weird and wonderful ways, Dr. Conway also lets your programs
<em>write</em> those parts!
</p>
<p>
If your program file is <em>writable</em>, all its virtual files
are opened in read-write mode. To rewrite the file, just
<tt>[seek]</tt> back to the beginning and rewrite it. (Or be more
creative if you like.) You can even create <em>new</em> virtual
files as your program is running.
</p>
<p>
This is a cheap and useful way of keeping some "sticky"
configuration data attached to your Perl scripts (note, however,
that this is per-script or per-module configuration data, rather
than per-user or per-instance data).
</p>
<p>
See the fine manual and the examples provided with the module in
the <tt>demo/</tt> subdirectory for more examples.
</p>
<h4>What <tt>-backup</tt> does</h4>
<p>
<small>
If your program is writing virtual files, you should be very
afraid: Your program is getting rewritten to disk continually.
<tt>-backup</tt> makes a backup copy of your program when it
loads, just in case. Use it if you're writing to virtual files!
</small>
</p>
<h3>Prerequisites</h3>
<p>
<tt>Inline::Files</tt> is a pure Perl extension, and doesn't
require a C compiler to install. It <em>does</em> require that
you have <tt>[Filter::Util]</tt> installed for your Perl, and
<em>that</em> extension contains some C files.
</p>
Multiple virtual files at the end of your code