我正在开发一个应用程序,它必须逐块替换现有的意大利面条代码。为了达到这个目的,我有一个调度器,它在URI匹配时运行所需的HTTP资源,否则使用传统的HTTP资源类。有没有办法在Perl中模拟内置的require函数?
因此,这个传统的HTTP资源必须require
旧系统的入口点文件,我想弄清楚如何测试这个过程。我现在看到的方式是我想用模拟子程序替换原始的require
函数,并检查它是否已用适当的文件名称进行调用。
这是可能的,如果没有,也许有更好的方法来做到这一点?
我正在开发一个应用程序,它必须逐块替换现有的意大利面条代码。为了达到这个目的,我有一个调度器,它在URI匹配时运行所需的HTTP资源,否则使用传统的HTTP资源类。有没有办法在Perl中模拟内置的require函数?
因此,这个传统的HTTP资源必须require
旧系统的入口点文件,我想弄清楚如何测试这个过程。我现在看到的方式是我想用模拟子程序替换原始的require
函数,并检查它是否已用适当的文件名称进行调用。
这是可能的,如果没有,也许有更好的方法来做到这一点?
一种更好的方式来覆盖require
全局可在中安装挂钩3210。这个鲜为人知的功能在the require
documentation的末尾进行了描述。
这里有一个简单的例子,用于拦截模块名称以HTTP的任何请求:
BEGIN {
unshift @INC, sub {
my ($self, $file) = @_;
return unless $file =~ /^HTTP/;
print "Creating mock $file\n";
my @code = "1"; # Fake module must return true
return sub { $_ = shift @code; defined $_ };
}
}
require HTTP::Foo;
use HTTPBar;
注意,因为它是基于require
,这也嘲笑use
。
要在单个封装覆盖require
:
use subs 'require'; # imports `require` so it can be overridden
sub require {print "mock require: @_\n"}
要覆盖require
全局:
BEGIN {
*CORE::GLOBAL::require = sub {print "mock require: @_\n"}
}
然后:
require xyz; # mock require: xyz.pm
require Some::Module; # mock require: Some/Module.pm
你需要注意的其他一些东西。这要么补充或取代覆盖require
的需要。
您是否知道您可以在您的@INC
路径中添加钩子作为代码参考?这些将在全球范围内适用于use
和require
报表。
引用的perldoc require
您也可以通过将Perl代码直接到@INC数组插入挂钩插入导入工具。
有三种形式的钩子:子程序引用,数组引用和祝福对象。
子程序引用是最简单的情况。当包含系统遍历@INC并遇到一个子例程时,这个子例程会被调用两个参数,第一个是对自身的引用,第二个是要包含的文件名(例如“Foo/Bar.pm”) 。该子程序应该按照下面的顺序返回任何内容或者最多三个值的列表:
1.一个文件句柄,从中读取文件。
2.对子程序的引用。如果没有文件句柄(前一个项目),那么这个子程序应该为每个调用产生一行源代码,将行写入$ _并返回1,最后在文件结尾返回0。如果存在文件句柄,则将调用该子例程以充当简单源过滤器,其中该行在$ _中读取。再次,每个有效行返回1,所有行返回后返回0。
3.子程序的可选状态。状态以$ _ [1]的形式传入。在子程序自身的引用传入为$ _ [0]
下面是一个例子:
#!/usr/bin/perl
sub my_inc_hook {
my ($sub_ref, $file) = @_;
unless ($file =~ m{^HTTP/}) {
warn "passing through: $file\n";
return;
}
warn "grokking: $file\n";
return (\*DATA);
}
BEGIN {
unshift(@INC, \&my_inc_hook);
}
use strict;
require warnings;
require HTTP::Bazinga;
HTTP::Bazinga::it_works();
__DATA__
package HTTP::Bazinga;
sub it_works {warn "bazinga!\n"};
1;
产地:
$ perl inc.pl
passing through: strict.pm
passing through: warnings.pm
grokking: HTTP/Bazinga.pm
bazinga!
我相信这个工程的Perl 5.10.0以上。
它也适用于5.8。 – cjm
感谢您的延伸解释,我已经接受了类似的答案,我相信这是第一个发布。 –
难道这不会模拟只有该模块的“需要”功能吗?我也需要它为所有其他模块嘲笑。 –
是的,请参阅全局版本的更新。 –
谢谢,它的工作原理,但我决定使用钩子。 –