¿Cómo se implementan los pragmas de alcance léxico de Perl?
-
13-12-2019 - |
Pregunta
Pragmas, como autodie
, según los documentos, tienen un alcance léxico.
{
use autodie;
..
..
}
# Can die here
¿Esto se aplica a todos los módulos cargados con use
?Por lo que yo sé, use
es casi lo mismo que:
BEGIN {
require autodie;
autodie->import(LIST);
}
BEGIN
ocurre en el momento de la compilación y require no tiene alcance léxico.Entonces, cómo es autodie
consciente de su alcance?
Solución
La respuesta corta es que léxicamente alcanzada módulos pragmáticos se escribe explícitamente para comportarse de esa manera, y use el Variables internas mágicas $^H
y %^H
durante el tiempo de compilación para habilitar y deshabilitar las características.
El compilador desempeña su parte al localizar implícitamente estas variables, por lo que su valor se restaura al final de la compilación de un bloque de código a lo que fue al principio. De esa manera, proporciona la base de la semántica léxica.
Originalmente solo la variable $^H
estaba disponible. Contiene una máscara de bits que dicta qué opciones del compilador están disponibles en cualquier momento durante la compilación. Debido a que las únicas pragmas léxicas que podrían ser escritas fueron las que manipulaban el conjunto definido de bits de magia en $^H
.
Más tarde se introdujo el hash %^H
, y cualquier pragma ahora puede almacenar valores en este hash con las teclas que comienzan con el nombre del pragma. Debido a que el compilador localiza el hash de la misma manera que el escalar, cualquier PRAGMA puede almacenar aquí automáticamente la información de estado aquí.
El módulo GeneracDicEtGodeCode no manipula ninguna de estas variables, sino también subclase el módulo autodie
que hace todo el trabajo duro. Utiliza Fatal
para realizar un seguimiento de los cuales los operadores se han hecho fatales, y se basan en el compilador para descartar esta información al final del bloque.
Otros consejos
del método de importación de Fatal.pm
, que es el backend de autodie
, disfrute de esto:
# Dark magic to have autodie work under 5.8
# Copied from namespace::clean, that copied it from
# autobox, that found it on an ancient scroll written
# in blood.
# This magic bit causes %^H to be lexically scoped.
$^H |= 0x020000;
Por lo tanto, la respuesta es que realmente hay una manera de informar a sus importaciones de su alcance léxico, pero está profundamente enredado con las agallas de PERL y no significa que los programadores ordinarios se usen.
Que no es require
Es interesante;es lo que hace el pragma en import
.
La mayoría (¿todos?) de los pragmas utilizan $^H
o %^H
.El analizador los localiza en el alcance que se está analizando, lo que significa que los restaura al valor que tenían antes.
Llevar estricto, Por ejemplo.Es import
modifica $^H
. $^H
contiene una serie de indicadores que indican al compilador cómo comportarse.
$ perl -e'
BEGIN { printf "%04X\n", $^H }
{
use strict;
BEGIN { printf "%04X\n", $^H }
}
BEGIN { printf "%04X\n", $^H }
'
0100
0702
0100
$^H
está reservado para el uso de Perl, pero localizado de manera similar %^H
está disponible para uso general.Por ejemplo, característica::qw_comment se engancha al analizador una vez, cuando lo carga require
, pero no hace nada a menos que $^H{'feature::qw_comments::'}
es verdad.Su importación equivale a
sub import { $^H{'feature::qw_comments::'} = 1; }