Frage

Pragmas, wie autodie, laut den Dokumenten, sind lexikalisch begrenzt.

{
use autodie;
  ..
  ..
}
# Can die here

Gilt dies für alle Module, die mit geladen wurden use?Soweit ich weiß, use ist fast das gleiche wie:

BEGIN {
  require autodie;
  autodie->import(LIST);
}

BEGIN geschieht zur Kompilierungszeit und require ist nicht lexikalisch begrenzt.Also, wie ist autodie sich seines Umfangs bewusst?

War es hilfreich?

Lösung

Die kurze Antwort lautet: lexikalisch pragmatische Module sind explizit so geschrieben, dass sie sich so verhalten und die magischen internen Variablen verwenden $^H und %^H während der Kompilierzeit, um Funktionen zu aktivieren und zu deaktivieren.

Der Compiler spielt seine Rolle, indem er diese Variablen implizit lokalisiert, sodass ihr Wert am Ende der Kompilierung eines Codeblocks auf den Wert von Anfang an wiederhergestellt wird.Auf diese Weise bildet es die Grundlage der lexikalischen Semantik.

Ursprünglich nur die $^H variabel verfügbar war.Es enthält eine Bitmaske, die vorschreibt, welche Compiler-Optionen zu jedem Zeitpunkt während der Kompilierung verfügbar sind.Aus diesem Grund waren die einzigen lexikalischen Pragmas, die geschrieben werden konnten, diejenigen, die den definierten Satz von magischen Bits manipulierten $^H.

Später die %^H hash wurde eingeführt, und jedes Pragma kann jetzt Werte in diesem Hash mit Schlüsseln speichern, die mit dem Namen des Pragmas beginnen.Da der Compiler den Hash auf die gleiche Weise wie den Skalar lokalisiert, kann jedes Pragma hier automatisch bereichsbezogene Statusinformationen speichern.

Der autodie modul manipuliert keine dieser Variablen, sondern unterklassifiziert die Fatal modul, das die ganze harte Arbeit erledigt.Es verwendet %^H um zu verfolgen, welche Operatoren tödlich gemacht wurden, und verlässt sich darauf, dass der Compiler diese Informationen am Ende des Blocks verwirft.

Andere Tipps

Aus der Importmethode von Fatal.pm welches ist das Backend von autodie, genieße das:

# 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;

Die Antwort ist also, dass es wirklich eine Möglichkeit gibt, Ihre Importe auf ihren lexikalischen Umfang aufmerksam zu machen, aber sie ist tief mit den Eingeweiden von Perl verwoben und nicht für normale Programmierer gedacht.

Es ist nicht require das ist interessant;es ist das, was das Pragma tut import.

Die meisten (alle?) pragmas verwenden $^H oder %^H.Der Parser lokalisiert diese auf den zu analysierenden Bereich, dh er stellt sie auf den Wert zurück, den sie zuvor hatten

Nehmen streng, beispielsweise.Seiner import ändern $^H. $^H enthält eine Reihe von Flags, die dem Compiler Anweisungen zum Verhalten geben.

$ perl -e'
    BEGIN { printf "%04X\n", $^H }
    {
       use strict;
       BEGIN { printf "%04X\n", $^H }
    }
    BEGIN { printf "%04X\n", $^H }
'
0100
0702
0100

$^H ist für Perls Verwendung reserviert, aber ähnlich lokalisiert %^H ist für den allgemeinen Gebrauch verfügbar.Beispielsweise, feature::qw_kommentar hakt sich einmal in den Parser ein, wenn er von geladen wird require, aber tut nichts, außer $^H{'feature::qw_comments::'} ist wahr.Sein Import entspricht

sub import { $^H{'feature::qw_comments::'} = 1; }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top