Perl realmente no le gusta el concepto de subrutinas final
, pero puede intentarlo. Teniendo en cuenta lo siguiente:
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
}
}
}
A continuación, podría escribir:
use warnings;
use strict;
{
package Foo;
sub hello {print "HI"}
use final 'hello';
}
package main;
no warnings;
sub Foo::hello {print "bye"}
Foo::hello();
que imprimirá algo como:
final subroutine Foo::hello was redefined at filename.pl line 9.
bye
La advertencia está impreso justo antes de la subrutina redefinido se llama en primer lugar, no se cuando en realidad se redefine (debido a las limitaciones del trabajo de perl y Variable::Magic
). Pero es mejor que nada.
no warnings;
está ahí porque perl normalmente lanzará una advertencia cuando se redefinan las subrutinas. Así que tal vez decirle a tus usuarios que use warnings
es lo suficientemente bueno. Como Larry ha dicho:
Perl no tiene un enamoramiento con la privacidad impuesta. Sería preferiría que se quedara fuera de su sala de estar porque no estaba invitado, no porque tenga una escopeta.
Es bien sabido que Perl a menudo te ofrece toda la cuerda que deseas, y es solo una convención lo que te impide hacer lo que no debes hacer (por ejemplo, jugar con métodos "finales" o "privados"). Si no puede aceptar eso, entonces Perl probablemente no sea el idioma para usted. – runrig
¿Hay algún problema que intente resolver o solo tiene curiosidad? –
Esto parece un concepto ajeno que no tiene sentido en Perl. ¿Qué intentas/quieres hacer en realidad y por qué? ¿Cuál es el verdadero objetivo? – tchrist