This module allows you to treat a single disk file as a collection of virtual files, which may then be
individually opened for reading or writing. Virtual files which have been modified are written back to
their actual disk at the end of the program's execution (or earlier if the "vf_save" subroutine is
explicitly called).
Each such virtual file is introduced by a start-of-virtual-file marker (SOVFM). This may be any sequence
(or pattern) of characters that marks the beginning of the content of a virtual file. For example, the
string "--" might be used:
--
Contents of virtual
file number 1
--
Contents of virtual
file number 2
--
Contents of virtual
file number 3
or the pattern "/##### \w+ #####/":
##### VF1 #####
Contents of virtual
file number 1
##### VF2 #####
Contents of virtual
file number 2
##### VF3 #####
Contents of virtual
file number 3
Note that the SOVFM is not considered to be part of the file contents.
Interface
The module exports the following methods:
"vf_load $file, $SOVFM_pattern"
This subroutine is called to load an actual disk file containing one or more virtual files. The first
argument specifies the name of the file to be loaded as a string. The second argument specifies a
pattern (as either a string or "qr" regex) that matches each start-of-virtual-file marker within the
file. For example, if the file "/usr/local/details.dat" contains:
=info names
Damian
Nathan
Mephistopheles
=info numbers
555-1212
555-6874
555-3452
=info comment
Mad
Bad
Dangerous to know
then you could load it as three virtual files with:
@virtual_filenames =
vf_load("/usr/local/details.dat", qr/^=info\s+\S+\s*?\n/);
Note that, because the actual file is decomposed into virtual files using a "split", it is vital that
the pattern does not contain any capturing parentheses.
On success, "vf_load" returns a list of virtualfilenames for the virtual files. Each virtual
filename consists of the actual name of the file containing the virtual file, concatenated with the
offset of the virtual file's SOVFM within the actual file. For example, the above call to "vf_load"
would return three virtual filenames:
/usr/local/details.dat(00000000000000000000)
/usr/local/details.dat(00000000000000000048)
/usr/local/details.dat(00000000000000000097)
When any of these virtual filenames is subsequently used in an "open", the corresponding virtual file
is opened.
"vf_save @actual_filenames"
"vf_save"
This subroutine causes the virtual files belonging to the nominated actual file (or files) to be
written back to disk. If "vf_save" is called without arguments, then all currently loaded virtual
files are saved to their respective actual files at that point.
"vf_save" is automatically called in an "END" block at the termination of any program using the
module.
"vf_marker $virtual_filename"
This subroutine returns the SOVFM that preceded the nominated virtual file.
The module also modifies the "open", "close", "print", "printf", "read", "getline", "getc", "seek",
"tell", and "truncate" built-in functions so that they operate correctly on virtual files.
As a special case, it is also possible to use the raw SOVFM as a virtual file name:
use Inline::Files::Virtual;
vf_load $filename, qr/__[A-Z]+__/;
open FILE, "__MARKER__";
# and in the file that was vf_load-ed
__MARKER__
file contents here
However, this always opens the very first virtual file with that SOVFM, no matter how often it is called,
or how many such markers appear in the file.
Handling"implicit"virtualstart-of-virtual-filemarkers
Sometimes an SOVFM is "implicit". That is, rather thanb being a separate marker for the start of a
virtual file, it is the first part of the actual data of the virtual file. For example, consider the
following XML file:
<DATA>
<DESC>This is data set 1</DESC>
<DATUM/>datum 1
<DATUM/>datum 2
<DATUM/>datum 3
</DATA>
<DATA>
<DESC>This is data set 2</DESC>
<DATUM/>datum 4
<DATUM/>datum 5
<DATUM/>datum 6
</DATA>
Each of the "<DATA>...</DATA>" blocks could be treated as a separate virtual file by specifying:
@datasets = vf_load("data.xml", '<DATA>');
But this would cause the individual virtual files to contain invalid XML, such as:
<DESC>This is data set 1</DESC>
<DATUM/>datum 1
<DATUM/>datum 2
<DATUM/>datum 3
</DATA>
One can indicate that the nominated SOVFMs are also part of the virtual files' contents, by specifying
the markers as a look-ahead pattern:
@datasets = vf_load("data.xml", '(?=<DATA>)');
This causes "vf_load" to identify the sequence "<DATA>" as a start-of-virtual-file marker but not consume
it, thereby leaving it as the initial sequence of the virtual file's content.