我知道如何覆盖perl
中的内置函数,并且我已覆盖die
warn
say
,因为print
和printf
可以没有被覆盖我把它绑在我的日志框架的句柄上。
覆盖warn
:
BEGIN{ *CORE::GLOBAL::warn = sub {
my ($package, $filename, $line, $subroutine) = caller;
untie *STDERR;
my $message;
foreach my $arg (@_) {
$message = $message.$arg;
}
print STDERR $message;
tie *STDERR, __PACKAGE__, (*STDERR);
logmessage("warn",$message,$filename, $line);
return;
}
}
现在我可以覆盖croak cluck confess carp
中carp
模块中的Perl
吗?
答案 0 :(得分:6)
Carp提供的函数只是常规函数,当模块为RewriteCond %{HTTP_HOST} ^example\.com [NC,OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
d时,它将通过Exporter导入到包中。诀窍是尽可能早地在use
命名空间内覆盖它们,然后才能导入它们。然后当他们这样做时,他们会得到被覆盖的。
在您的脚本中,或在您自己的日志记录模块的最顶层:
Carp
您需要加载Carp一次,以便Perl解析代码并在BEGIN {
require Carp;
# save original croak (will create closure ...)
my $original_croak = \&Carp::croak;
no warnings 'redefine';
*Carp::croak = sub {
print "Croaking...\n"
or $original_croak->("cannot fake croak"); # (... here)
};
}
命名空间中安装这些函数。然后你可以覆盖它们。
稍后,在代码中的其他模块中:
Carp
这将产生我们在上面设置的输出。
如果您想在新内容中调用原始use Carp 'croak';
croak 'foo';
,请将其保存到coderef并保留,如上例所示。
请注意,这仅在替换发生得非常早时才有效。如果你把它放在你自己的日志记录模块中,并且在Carp加载后它被加载,那么这将失败。
Carp::croak
无法使用,因为在您覆盖package Foo;
use Carp;
use Your::Logging::Framework;
croak 'foo';
时,Carp::croak
已经是原始Foo::croak
的副本。
如果您希望这样做,您可以随时将自己的Carp::croak
,carp
等导入到调用方。这会在croak
下引发一堆警告或抱怨,但它应该有用。