Dado que las constantes son subrutinas y puede obtener la herencia llamándolas como métodos, el bit ya se ha cubierto hasta la muerte, aquí hay un giro diferente en las cosas.
Si sabe que está trabajando solamente en un solo archivo, puede utilizar las constantes léxicas a los paquetes de puente:
package Parent;
our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL);
*NO_LEVEL = \0; # this split declaration installs aliases to numbers
*MY_LEVEL = \1; # into the lexicals. since numbers are constants
*YOUR_LEVEL = \2; # to perl, the aliased names are also constants
package Child;
# just to demonstrate that anything below can access the constants
sub printAll {
print "$NO_LEVEL $MY_LEVEL $YOUR_LEVEL\n";
}
Child->printAll; # 0 1 2
eval {$NO_LEVEL = 3} or print "error: [email protected]\n";
# error: Modification of a read-only value attempted at ...
Si usted no necesita Perl a morir cuando se asigna a la constante, la declaración our
se hace un poco más simple (y podría ser una my
):
our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2);
puede traer de vuelta a la naturaleza constante sin dejar de utilizar la sintaxis concisa con un poco de magia:
my $constant = sub {Internals::SvREADONLY($_[$_], 1) for 0 .. $#_};
package Parent;
$constant->(our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2));
package Child;
# just to demonstrate that anything below can access the constants
sub printAll {
print "$NO_LEVEL $MY_LEVEL $YOUR_LEVEL\n"; # interpolates :)
}
Child->printAll; # 0 1 2
eval {$NO_LEVEL = 3} or print "error: [email protected]\n";
# error: Modification of a read-only value attempted at ...
Por supuesto, puede omitir el coderef $constant
en línea y de la magia:
package Parent;
Internals::SvREADONLY($_, 1)
for our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2);
+1 por una respuesta completa. Esto realmente me ayudó a entender la situación aquí. ¡Gracias, Eric! – qodeninja