Comment sont-Perl lexicalement étendue de pragmas mis en œuvre?
-
13-12-2019 - |
Question
Pragmas, comme autodie
, selon les docs, sont lexicalement étendue.
{
use autodie;
..
..
}
# Can die here
Cela s'applique à tous les modules chargés avec use
?Autant que je sache, use
c'est presque la même chose que:
BEGIN {
require autodie;
autodie->import(LIST);
}
BEGIN
qui se passe au moment de la compilation, et le besoin n'est pas lexicalement étendue.Alors, comment est autodie
conscient de sa portée?
La solution
La réponse courte est que lexicalement étendue pragmatique modules sont explicitement écrit à se comporter de cette façon, et d'utiliser la magie des variables internes $^H
et %^H
lors de la compilation pour activer et désactiver des fonctionnalités.
Le compilateur joue son rôle, même implicitement la localisation de ces variables ainsi que leur valeur est restaurée à la fin de la compilation d'un bloc de code pour ce qu'il était au début.De cette façon, il fournit la base de la sémantique lexicale.
A l'origine, seule la $^H
variable a été disponible.Il contient un masque de bits qui dicte les options du compilateur sont disponibles à tout moment lors de la compilation.Parce que la seule lexicale pragmas qui peut être écrite, ont été ceux qui a manipulé l'ensemble défini de la magie bits $^H
.
Plus tard, le %^H
de hachage a été introduit, et tout pragma peut maintenant stocker les valeurs de hachage avec des clés de commencer avec le nom de la pragma.Parce que le compilateur localise le hachage de la même manière que le scalaire, tout pragma peut stocker automatiquement l'étendue des informations d'état ici.
L' autodie
le module ne manipule pas l'une de ces variables, mais les sous-classes de la Fatal
module qui fait tout le travail dur.Il utilise %^H
pour garder une trace de ce que les opérateurs ont été faites fatale, et s'appuie sur le compilateur de jeter cette information à la fin du bloc.
Autres conseils
À partir de la méthode d'importation de Fatal.pm
qui est le backend de autodie
, profitez de ce site:
# 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;
Donc la réponse est qu'il est vraiment une façon de faire de vos importations conscience de leur portée lexicale, mais il est empêtré avec les tripes de perl et pas fait pour le commun des programmeurs.
Ce n'est pas require
c'est intéressant;c'est ce que le pragma n'en import
.
La plupart (tous?) pragmas utilisation $^H
ou %^H
.L'analyseur localise ces à la portée pour être analysée en ce sens qu'elle redonne à la valeur qu'ils avaient avant
Prendre stricte, par exemple.Son import
modifie $^H
. $^H
contient une série d'indicateurs qui indique au compilateur comment se comporter.
$ perl -e'
BEGIN { printf "%04X\n", $^H }
{
use strict;
BEGIN { printf "%04X\n", $^H }
}
BEGIN { printf "%04X\n", $^H }
'
0100
0702
0100
$^H
est réservé pour Perl à l'usage, mais de la même façon localisée %^H
est disponible pour une utilisation générale.Par exemple, fonctionnalité::qw_comment des crochets dans le parser une fois, quand il est chargé par require
, mais ne rien faire, à moins que $^H{'feature::qw_comments::'}
est vrai.C'est l'importation est équivalent à
sub import { $^H{'feature::qw_comments::'} = 1; }