File-VirtualPath
view release on metacpan or search on metacpan
lib/File/VirtualPath.pm view on Meta::CPAN
# as Perl itself. However, I do request that this copyright information and
# credits remain attached to the file. If you modify this module and
# redistribute a changed version then please attach a note listing the
# modifications. This module is available "as-is" and the author can not be held
# accountable for any problems resulting from its use.
use strict;
use warnings;
use vars qw($VERSION);
$VERSION = '1.011';
######################################################################
=head1 DEPENDENCIES
=head2 Perl Version
5.004
=head2 Standard Modules
I<none>
=head2 Nonstandard Modules
I<none>
=head1 SYNOPSIS
=head2 Content of thin shell "startup.pl":
#!/usr/bin/perl
use strict;
use warnings;
my $root = "/home/johndoe/projects/aardvark";
my $separator = "/";
if( $^O =~ /Win/i ) {
$root = "c:\\projects\\aardvark";
$separator = "\\";
}
if( $^O =~ /Mac/i ) {
$root = "Documents:projects:aardvark";
$separator = ":";
}
use Aardvark;
Aardvark->main( File::VirtualPath->new( $root, $separator ) );
1;
=head2 Content of fat main program "Aardvark.pm"
package Aardvark;
use strict;
use warnings;
use File::VirtualPath;
sub main {
my (undef, $project_dir) = @_;
my $prefs = &get_prefs( $project_dir->child_path_obj( 'config.pl' ) );
&do_work( $prefs, $project_dir );
}
sub get_prefs {
my ($project_dir) = @_;
my $real_filename = $project_dir->physical_path_string();
my $prefs = do $real_filename;
defined( $prefs ) or do {
my $virtual_fn = $project_dir->path_string();
die "Can't get Aardvark prefs from file '$virtual_fn': $!";
};
return( $prefs );
}
sub do_work {
my ($prefs, $project_dir) = @_;
my ($lbl_a, $lbl_b, $lbl_c) = ($prefs->{a}, $prefs->{b}, $prefs->{c});
my $data_source = $prefs->{'sourcefile'};
open( SOURCE, $project_dir->physical_child_path_string( $data_source ) );
while( my $line = <SOURCE> ) {
my ($a, $b, $c) = split( "\t", $line );
print "File contains: $lbl_a='$a', $lbl_b='$b', $lbl_c='$c'\n";
}
close( SOURCE );
}
1;
=head2 Content of settings file "config.pl"
$rh_prefs = {
sourcefile => 'mydata.txt',
a => 'name',
b => 'phone',
c => 'date',
};
=head1 DESCRIPTION
This Perl 5 object class implements a portable abstraction of a resource path,
examples of which include file-system paths like "/usr/bin/perl" and URLs like
"http://www.cpan.org/modules/". It is designed to support applications that are
easily portable across systems because common platform-specific details are
abstracted away. Abstracted details include the location of your project within
the file-system and the path separator for your OS; you can write your
application as if it is in the root directory of a UNIX system, and it will
function correctly when moved to any subdirectory or to a Mac or Windows system.
=head1 OVERVIEW
This class is implemented as a simple data structure which stores an array of
path segments such as ['', 'usr', 'bin', 'perl'] in a virtual file-system. The
majority part of your application works with these objects and passes them around
during its routines of locating config or data or other files.
As your application navigates the virtual file-system, it uses object methods
like chdir() to tell the object where the app thinks it is now. When your
program actually needs to use files, it asks a method like physical_path_string()
to give it a string representing the current path in the real world, which it
then passes to your standard I/O functions like open().
For example, the program may think it is sitting in "/config/access", but it
actually makes an open call to "/home/johndoe/projects/aardvark/config/access".
If you move the "aardvark" project to a Windows system, the real path may have
changed to "c:\projects\aardvark\config\access", but your program would never
need to know the difference (aside from any internal file format issues).
In order for this to work, a small part of your program needs to know the truth
of where the project it is working on is located. But that part can be a very
lightweight shim which initializes a single File::VirtualPath object and then
passes it to the fat portable part of the program. There are two bits of data
that your shim needs to provide: 1. A string having the full real-world path of
your project root directory; 2. A string having the real-world path separator.
See the SYNOPSIS for an example.
Then, your main program just needs to assume that the argument it was passed is
currently in the virtual root directory and go from there.
THIN CONFIG SHELL <----> File::VirtualPath <----> FAT PROGRAM CORE
(may be portable) (portable) (portable)
Taking this idea further, it is easy for program code to be reused for multiple
projects, simultaneously, because each would only need a different thin shim
program which points to a different physical directory as the virtual root.
Taking this idea further, File::VirtualPath makes it easier for you to separate
your application into components that have their own files to keep track of.
When your main program calls a component, it can pass a modified FVP object which
that component uses as its own virtual root. And so you can have multiple
instances of program components each working in different directories, and no
logic for working this out needs to be in the components themselves.
( run in 1.778 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )