Is there a way to easily package resource files with a Perl module? Right now, I'm using %INC to find the location of the module then loading my resource files, but I'm looking for a solution where Perl will automatically reference the correct path (similar to how Java's class resources work).
Perl Module Resource Files
473 Views Asked by SArcher At
2
There are 2 best solutions below
3

%INC
approach is actually pretty good.
If you want it generic, you can wrap it up in a little module and use caller(0)
for getting the parent module (caller(0)
will return an array whose second element will be the same as %INC
value for your module)
Here's my sample code (I tested it but won't include full test code for brevity):
package ModulePath;
# This module can be used for getting resource files
# In the same directory as a Perl module
use File::Basename;
use File::Spec;
sub path {
my @c=caller(0);
return dirname($c[1]);
}
sub default_resource {
my $resource_suffix = shift || "txt";
my @c=caller(0);
my @suffixes = ("pm");
my ($name,$path,$suffix) = fileparse($c[1], @suffixes);
my $file = File::Spec->catfile(dirname($c[1]), "$name$resource_suffix");
return $file;
}
1;
And here's the SYNOPSIS (from a librery called "p/a.pm" I just wrote and tested)
# Get directory, supply resource file name
my $path = ModulePath::path();
my $file = File::Spec->catfile($path,"b.txt");
# Get default resource (module name with ".txt" suffix)
my $file2 = ModulePath::default_resource();
# Get resource with default name (same as module) but non-default suffix
my $file3 = ModulePath::default_resource("dat");
Test results (abriged):
$VAR2 = 'C:\\_Code\\so\\20864526\\p\\b.txt';
$VAR1 = 'C:\\_Code\\so\\20864526\\p\\a.txt';
$VAR1 = 'C:\\_Code\\so\\20864526\\p\\a.dat';
File::ShareDir for loading resources at run-time.
File::ShareDir::Install orModule::Install::Share or Dist::Zilla::Plugin::ModuleShareDirs or Dist::Zilla::Plugin::ShareDir for handling the install-time copying of files.
(You may be wondering about why Dist::Zilla includes two plugins for doing this sort of thing. Reading the File::ShareDir documentation should make it clear - File::ShareDir allows you to install resource files in two different locations - one which is grouped by module name (e.g. Foo::Bar), and one which is grouped by distribution name (e.g. Foo-Bar). When you're creating distributions with more than one module, this is an important distinction.)