Aren't you simply looking for
use FindBin qw( $RealBin );
use lib "$RealBin/..";
Вопрос
I'm going to refactoring large number of old perl scripts. (over 150k lines, no tests, no strict, no packages, no commit logs, no comments)
When I started to write some tests under t
directory. I found almost all files require
each others with absolute paths. So I tried mocking builtin require
function to make them portable, but no luck:
use strict;
use warnings;
use Test::More;
use FindBin;
BEGIN {
my $root = "$FindBin::RealBin/../";
sub require {
$_[0] = $root . $_[0];
CORE::require(@_);
}
}
require_ok "foo.pl";
done_testing();
The above script gives me: Error: Can't locate foo.pl in @INC...
How can I prepend a root path before Perl requires them?
Thank you Axeman, I modified absolute paths using following hook.
my $root = "$RealBin/../";
unshift @INC, sub {
my ($coderef, $filename) = @_;
$filename =~ s/^\///;
open(FILE, '<', $root . $filename);
return *FILE;
};
Решение
Aren't you simply looking for
use FindBin qw( $RealBin );
use lib "$RealBin/..";
Другие советы
You don't have to.
When a module is require
d, either by require
or use
, perl looks through a list to see if it can locate the module by the list of (usually) directories set up as libraries for the installation. This list is stored in a variable called @INC
.
However, @INC
takes more than directories, it also takes "hooks", which are subroutines which can change the loading behavior for Perl modules. If you insert a hook (a subroutine) as the first entry into @INC
, require will call your behavior.
You can find a more complete treatment at the perldoc on require
. I just wanted to give a quick profile of a hook:
sub inc_hook {
my ( $ref_to_this_sub, $relative_module_path ) = @_;
# $relative_module_path will be in directory form: Root/Package.pm
# return nothing to pass it to standard behavior
return unless _i_want_to_handle( $relative_module_path );
# most commonly, return handle to source
return my $io_handle_to_source = handle_module( $relative_module_path );
}
unshift @INC, inc_hook;