Преобладающий хриплый клоун исповедует карпа из модуля карпа в Perl
Я знаю, как переопределить встроенные функции в 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
?
1 ответ
Функции, предоставляемые Carp, являются обычными функциями, которые импортируются в ваши пакеты через Exporter, когда модуль use
д. Хитрость заключается в том, чтобы перезаписать их как можно раньше внутри 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
,
Если вы хотите сделать эту работу, вы всегда можете импортировать свой собственный carp
, croak
и так далее для вызывающего абонента также. Это бросит кучу предупреждений или пожаловаться под strict
, но это должно работать.