Perl не очень нравится концепция final
подпрограмм, но вы можете попробовать. Учитывая следующее:
BEGIN {
package final;
$INC{'final.pm'}++;
use Variable::Magic qw(wizard cast);
sub import {
my (undef, $symbol) = @_;
my ($stash, $name) = $symbol =~ /(.+::)(.+)/;
unless ($stash) {
$stash = caller().'::';
$name = $symbol;
$symbol = $stash.$name;
}
no strict 'refs';
my $glob = \*$symbol;
my $code = \&$glob;
my ($seen, @last);
cast %$stash, wizard store => sub {
if ($_[2] eq $name and $code != \&$glob) {
print "final subroutine $symbol was redefined ".
"at $last[1] line $last[2].\n" unless $seen++
}
@last = caller
}
}
}
Вы можете написать:
use warnings;
use strict;
{
package Foo;
sub hello {print "HI"}
use final 'hello';
}
package main;
no warnings;
sub Foo::hello {print "bye"}
Foo::hello();
Который напечатает что-то вроде:
final subroutine Foo::hello was redefined at filename.pl line 9.
bye
Предупреждение выводится непосредственно перед первым вызовом переопределенной подпрограммы, а не тогда, когда она фактически переопределяется (из-за ограничений работы perl и Variable::Magic
). Но это лучше, чем ничего.
Здесь есть no warnings;
, поскольку perl обычно выдает предупреждение при переопределении подпрограмм. Поэтому, может быть, достаточно сказать своим пользователям use warnings
. Как сказал Ларри:
В Perl нет безумного увлечения принудительной приватностью. Было бы
предпочитаю, чтобы вы остались вне его гостиной, потому что вы не были
не потому, что у него есть дробовик.