[英]How can I mock builtin `require` function?
I'm going to refactoring large number of old perl scripts. 我要重构大量旧的perl脚本。 (over 150k lines, no tests, no strict, no packages, no commit logs, no comments)
(超过150k行,没有测试,没有严格,没有包,没有提交日志,没有评论)
When I started to write some tests under t
directory. 当我开始在
t
目录下编写一些测试时。 I found almost all files require
each others with absolute paths. 我发现几乎所有文件
require
绝对路径。 So I tried mocking builtin require
function to make them portable, but no luck: 所以我尝试使用内置的
require
函数来使它们可移植,但没有运气:
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...
上面的脚本给了我:
Error: Can't locate foo.pl in @INC...
How can I prepend a root path before Perl requires them? 如何在Perl需要之前添加根路径?
Thank you Axeman, I modified absolute paths using following hook. 谢谢Axeman,我使用以下钩子修改了绝对路径。
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. 当一个模块是
require
d,无论是require
或use
,PERL看起来在一个列表,看它是否可以通过设置为安装库(通常情况下)的目录列表中找到该模块。 This list is stored in a variable called @INC
. 该列表存储在名为
@INC
的变量中。
However, @INC
takes more than directories, it also takes "hooks", which are subroutines which can change the loading behavior for Perl modules. 但是,
@INC
需要的不仅仅是目录,它还需要“钩子”,这些子程序可以改变Perl模块的加载行为。 If you insert a hook (a subroutine) as the first entry into @INC
, require will call your behavior. 如果您将钩子 (子例程)作为第一个条目插入
@INC
,则require将调用您的行为。
You can find a more complete treatment at the perldoc on require
. 您可以在一个更完整的治疗上的perldoc
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.