我知道如何在perl中的内置函数中进行重写,并且我已经重写了die warn say,并且由于无法重写printprintf,因此将其与日志框架的句柄绑定(bind)在一起。

覆盖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吗?

最佳答案

Carp提供的功能只是常规功能,当模块为use d时,它们会通过Exporter导入到您的包中。技巧是在任何人都可以导入它们之前,在Carp命名空间内尽早覆盖它们。然后,当他们这样做时,他们会得到覆盖的。

在您的脚本中,或者在您自己的日志记录模块的最顶部:

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,以便Perl解析代码并将函数安装在Carp命名空间中。然后,您可以覆盖它们。

稍后,在代码中的其他模块中:
use Carp 'croak';

croak 'foo';

现在将产生我们上面设置的输出。

如果要在新代码中调用原始的Carp::croak,请将其保存到coderef中,并如上例所示将其保留。

请注意,这仅在替换发生得很早时才有效。如果将其放在自己的日志记录模块中,并且在Carp加载后加载,它将失败。
package Foo;
use Carp;
use Your::Logging::Framework;

croak 'foo';

将不起作用,因为在您覆盖Carp::croak的位置,Foo::croak已经是原始Carp::croak的副本。

如果您想完成这项工作,则始终可以将自己的carpcroak等也明确地导入调用者。这会在strict下引发一堆警告或抱怨,但它应该可以工作。

10-06 15:26