我怎样才能包装要求和使用?
How can I wrap require and use?
假设我想包装 require
这样,
package MyModule;
use Data::Dumper;
会输出,
MyModule -> Data::Dumper
MyModule -> Data/Dumper.pm
对于所有包和所有 requires
/use
语句。我该怎么做?
奇怪的要求需要奇怪的解决方案:使用源过滤器。
#!/usr/bin/perl
{ package Wrap::Use;
use Filter::Simple sub {
warn while /use (.*?);/sg; # stupid SO: /
};
}
BEGIN { Wrap::Use->import }
use strict;
use warnings;
use Time::Piece;
BEGIN {
unshift @INC, sub {
printf "%s -> %s\n", ( caller() )[0], $_[1];
return;
};
}
请参阅 require
's documentation 中以“您还可以将挂钩插入导入工具”开头的段落。
您不能将 require
内置函数作为子例程引用,例如 goto
,但您可以从 CORE.
中调用它
use strict;
use warnings;
BEGIN {
*CORE::GLOBAL::require = sub {
printf "%s -> %s\n", [caller()]->[0], $_[0];
CORE::require $_[0];
}
};
use Data::Dumper;
您也可以考虑 Devel::TraceUse,它与上述类似,但更健壮且信息更丰富,并且可以轻松地从命令行调用。
您可以查看内部 Devel::TraceUse 以查看您正在尝试执行的操作的工作代码。但是,更改定义并不是一个好的计划,因为您不知道还有谁也更改了定义,并且会想知道为什么他们的东西停止工作。
您不需要(也不应该)覆盖 require
。在 @INC
和 return false 末尾放置一个代码引用,这样看起来失败了,Perl 将继续 @INC
:
中的下一件事
#!perl
use v5.10;
#
BEGIN {
unshift @INC, sub {
my( $package, $file ) = caller(0);
say "$package -> $_[1]";
return 0;
};
}
use Data::Dumper;
say "Hello";
这输出:
main -> Data/Dumper.pm
Data::Dumper -> constant.pm
constant -> strict.pm
constant -> warnings/register.pm
warnings::register -> warnings.pm
Data::Dumper -> Carp.pm
Carp -> overloading.pm
Carp -> Exporter.pm
Data::Dumper -> XSLoader.pm
Data::Dumper -> bytes.pm
Hello
假设我想包装 require
这样,
package MyModule;
use Data::Dumper;
会输出,
MyModule -> Data::Dumper
MyModule -> Data/Dumper.pm
对于所有包和所有 requires
/use
语句。我该怎么做?
奇怪的要求需要奇怪的解决方案:使用源过滤器。
#!/usr/bin/perl
{ package Wrap::Use;
use Filter::Simple sub {
warn while /use (.*?);/sg; # stupid SO: /
};
}
BEGIN { Wrap::Use->import }
use strict;
use warnings;
use Time::Piece;
BEGIN {
unshift @INC, sub {
printf "%s -> %s\n", ( caller() )[0], $_[1];
return;
};
}
请参阅 require
's documentation 中以“您还可以将挂钩插入导入工具”开头的段落。
您不能将 require
内置函数作为子例程引用,例如 goto
,但您可以从 CORE.
use strict;
use warnings;
BEGIN {
*CORE::GLOBAL::require = sub {
printf "%s -> %s\n", [caller()]->[0], $_[0];
CORE::require $_[0];
}
};
use Data::Dumper;
您也可以考虑 Devel::TraceUse,它与上述类似,但更健壮且信息更丰富,并且可以轻松地从命令行调用。
您可以查看内部 Devel::TraceUse 以查看您正在尝试执行的操作的工作代码。但是,更改定义并不是一个好的计划,因为您不知道还有谁也更改了定义,并且会想知道为什么他们的东西停止工作。
您不需要(也不应该)覆盖 require
。在 @INC
和 return false 末尾放置一个代码引用,这样看起来失败了,Perl 将继续 @INC
:
#!perl
use v5.10;
#
BEGIN {
unshift @INC, sub {
my( $package, $file ) = caller(0);
say "$package -> $_[1]";
return 0;
};
}
use Data::Dumper;
say "Hello";
这输出:
main -> Data/Dumper.pm
Data::Dumper -> constant.pm
constant -> strict.pm
constant -> warnings/register.pm
warnings::register -> warnings.pm
Data::Dumper -> Carp.pm
Carp -> overloading.pm
Carp -> Exporter.pm
Data::Dumper -> XSLoader.pm
Data::Dumper -> bytes.pm
Hello