In Perl gibt es spezielle Blöcke (BEGIN, CHECK, INIT, END), die es ermöglichen, die Ausführungszeit von Code zu steuern:
BEGIN { ... } — wird sofort beim Kompilieren der Datei ausgeführt (vor dem Hauptcode und vor dem Laden von Modulen);CHECK { ... } — wird nach der Kompilierung aller Dateien, aber vor deren Ausführung ausgeführt (nicht in allen Perl-Versionen unterstützt);INIT { ... } — wird vor Beginn der Ausführung des Hauptcodes ("Laufzeit") ausgeführt;END { ... } — wird nach Abschluss des Programms, beim Verlassen des Skripts, ausgeführt.Die Ausführungsreihenfolge:
BEGINCHECKINITENDBeispiel:
BEGIN { print "BEGIN ausgeführt "; } CHECK { print "CHECK ausgeführt "; } INIT { print "INIT ausgeführt "; } print "Hauptcode ausgeführt "; END { print "END ausgeführt "; }
Kann ein BEGIN-Block innerhalb eines Moduls den globalen Zustand des Programms beeinflussen, wenn dieses Modul mit require anstatt mit use eingebunden wird?
Antwort und Beispiel:
BEGIN-Blöcke werden während der Kompilierung ausgeführt, daher werden sie nicht ausgeführt, wenn das Modul über require (zur Laufzeit, nicht zur Kompilierung) anstelle von use (wird während der Kompilierung der einbindenden Datei ausgeführt) eingebunden wird. Dies kann zu unerwartetem Verhalten führen, wenn die Initialisierung auf BEGIN gelegt wird.
Geschichte 1: In einem Projekt wurde
BEGINzur Initialisierung von Umgebungsvariablen verwendet, und das Modul wurde überrequireeingebunden — als Ergebnis wurden die Variablen nicht gesetzt, was Chaos beim Laden von Konfigurationen in der Produktion verursachte.
Geschichte 2: Bei der Verwendung des
END-Blocks zum Schließen von Dateideskriptoren wurden implizite Prozessstopps nicht berücksichtigt; manchmal wurde derEND-Block aufgrund eines unerwarteten Absturzes des Perl-Interpreters nicht ausgeführt, was zu verlorenen Daten in den Logs führte.
Geschichte 3: Die
CHECK-Blöcke waren der einzige Ort, an dem Tests zur Validierung der Umgebung ausgeführt wurden. Der Benutzer führte das Skript in einer alten Version von Perl aus, in der es keinenCHECK-Block gab, und die Überprüfungen wurden einfach nicht durchgeführt — kritische Fehler traten nur in der Produktion auf.