Como o Perl do léxico escopo pragmas implementado?
-
13-12-2019 - |
Pergunta
Pragmas, como autodie
, de acordo com o google docs, possuem escopo léxico.
{
use autodie;
..
..
}
# Can die here
Isso se aplica a todos os módulos carregados com use
?Até onde eu sei, use
é quase o mesmo que:
BEGIN {
require autodie;
autodie->import(LIST);
}
BEGIN
acontece em tempo de compilação, e precisa não é com escopo léxico.Então, como é autodie
ciente de seu âmbito de aplicação?
Solução
A resposta curta é que a léxico-escopo pragmática módulos são explicitamente escrito para se comportar dessa maneira, e usar o mágico variáveis internas $^H
e %^H
durante o tempo de compilação para habilitar e desabilitar os recursos.
O compilador desempenha o seu papel, implicitamente, localizando essas variáveis de modo que o seu valor é recuperado no final da compilação de um bloco de código para o que era no início.Dessa forma, fornecem a base do léxico-semântica.
Inicialmente, apenas o $^H
variável estava disponível.Ele contém uma máscara de bits que determina quais opções de compilador estão disponíveis a qualquer momento durante a compilação.Devido a que a única lexical pragmas que poderiam ser escritas foram os que manipulavam o conjunto definido de magia bits $^H
.
Mais tarde, o %^H
hash foi introduzido, e qualquer pragma agora pode armazenar valores neste hash com chaves que começam com o nome da pragma.Porque o compilador localiza o hash da mesma forma como o escalar, qualquer pragma pode armazenar automaticamente escopo informações de status aqui.
O autodie
módulo não manipular qualquer uma dessas variáveis, mas subclasses da Fatal
módulo que faz todo o trabalho duro.Ele usa %^H
para manter o controle de quais operadores foram feitas fatal, e depende do compilador para descartar essa informação no final do bloco.
Outras dicas
A partir do método de importação de Fatal.pm
qual é a infra-estrutura do autodie
, aproveite este:
# 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;
Então, a resposta é que há realmente uma maneira de fazer o seu importações conscientes de seu âmbito lexical, mas é profundamente interligada com a coragem de perl, e não se destina para o comum dos programadores para se usar.
Não require
que interessante;é o que o programa faz em import
.
A maioria (todos?) pragmas uso $^H
ou %^H
.O analisador localiza estes, para o escopo que está sendo analisada, ou seja, restaura-lhes o valor que tinha antes
Tomar estrito, por exemplo.O seu import
modifica $^H
. $^H
contém uma série de bandeiras que instrui o compilador como se comportar.
$ perl -e'
BEGIN { printf "%04X\n", $^H }
{
use strict;
BEGIN { printf "%04X\n", $^H }
}
BEGIN { printf "%04X\n", $^H }
'
0100
0702
0100
$^H
é reservado para o Perl de uso, mas da mesma forma localizada %^H
está disponível para uso geral.Por exemplo, recurso::qw_comment ganchos para o analisador, uma vez, quando ele é carregado por require
, mas não faz nada a menos que $^H{'feature::qw_comments::'}
é verdade.É importar é equivalente a
sub import { $^H{'feature::qw_comments::'} = 1; }