压倒呱呱叫咯咯从Perl的鲤鱼模块中忏悔

时间:2017-10-09 09:34:17

标签: perl die function-overriding carp

我知道如何覆盖perl中的内置函数,并且我已覆盖die warn say,因为printprintf可以没有被覆盖我把它绑在我的日志框架的句柄上。

覆盖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 carpcarp模块中的Perl吗?

1 个答案:

答案 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::croakcarp等导入到调用方。这会在croak下引发一堆警告或抱怨,但它应该有用。