Welche Rolle spielt der BEGIN-Block in Perl?
Ich weiß, dass der BEGIN-block wird kompiliert und ausgeführt, bevor der Hauptteil, ein Perl-Programm. Wenn Sie sich nicht sicher sind, die gerade versuchen, den Befehl ausführen perl -cw über diese:
#!/ms/dist/perl5/bin/perl5.8
use strict;
use warnings;
BEGIN {
print "Hello from the BEGIN block\n";
}
END {
print "Hello from the END block\n";
}
Habe ich gelernt, dass Anfang der Kompilierung und der Ausführung der BEGIN-block kann ein Programmierer sicherstellen, dass alle benötigten Ressourcen verfügbar sind, bevor das main-Programm ausgeführt wird.
Und so habe ich mit BEGIN-Blöcke, um sicherzustellen, dass Dinge wie DB-verbindungen eingerichtet wurden und verfügbar sind für die Nutzung durch das Hauptprogramm. Ebenso verwende ich ENDE Blöcke, um sicherzustellen, dass alle Ressourcen sind geschlossen, gelöscht, beendet, etc.. bevor das Programm beendet wird.
Nach einer Diskussion heute morgen Frage ich mich, ob dies der falsche Weg zu schauen, BEGIN-und END-Blöcke.
Was ist die vorgesehene Rolle von einem BEGIN-block in Perl?
Update 1: Gerade herausgefunden, warum das DBI-connect funktionierte nicht. Nach gegeben dieses kleine Perl-Programm:
use strict;
use warnings;
my $x = 12;
BEGIN {
$x = 14;
}
print "$x\n";
ausgeführt, wenn er druckt 12.
Update 2: Dank an Eric Strom Kommentar unterhalb dieser neuen version macht es deutlich:
use strict;
use warnings;
my $x = 12;
my $y;
BEGIN {
$x = 14;
print "x => $x\n";
$y = 16;
print "y => $y\n";
}
print "x => $x\n";
print "y => $y\n";
und der Ausgang ist
x => 14
y => 16
x => 12
y => 16
Nochmals vielen Dank Eric!
InformationsquelleAutor der Frage Rob Wells | 2010-10-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie versucht, den Austausch der
BEGIN{}
block für eineINIT{}
block? Das ist der standard-Ansatz für Dinge wie modperl verwenden Sie den "compile once, run many" - Modell, wie Sie brauchen, um zu initialisieren, die Dinge neu und auf jedem einzelnen laufen, nicht nur einmal während des kompilieren.Aber ich habe zu Fragen, warum es im speziellen block sowieso. Warum nimmst du nicht einfach eine Art von
prepare_db_connection()
Funktion, und dann nennen Sie es wie Sie brauchen, um, wenn das Programm startet?Etwas, das gewann ' T Arbeit in einer
BEGIN{}
haben auch das gleiche problem, wenn es die main-line-code in eine Modul-Datei, die bekommtuse
d. Das ist ein weiterer möglicher Grund für die Verwendung einerINIT{}
block.Ich habe auch gesehen, tödliche-Umarmung Probleme der gegenseitige Rekursion, die enträtselt, mit so etwas wie eine
require
stattuse
oder eineINIT{}
statt einerBEGIN{}
. Aber das ist ziemlich selten.Betrachten Sie dieses Programm:
Wenn nur kompiliert, erzeugt es:
Während bei der Kompilierung und ausgeführt, es produziert dies:
Und die shell meldet einen exit 255, pro die
die
.Sollten Sie in der Lage zu arrangieren, um die Verbindung geschehen, wenn Sie Sie brauchen, auch wenn ein
BEGIN{}
beweist zu früh.Hm, nur Erinnerung. Es gibt keine chance, Sie tun etwas mit
DATA
imBEGIN{}
gibt es? Das ist nicht festgelegt, bis der interpreter läuft, ist es auch nicht öffnen, um den compiler.InformationsquelleAutor der Antwort tchrist
Während
BEGIN
undEND
Blöcke können verwendet werden, wie Sie es beschreiben, die typische Verwendung ist, um änderungen, die Auswirkungen auf die nachfolgende Zusammenstellung.Beispielsweise die
use Module qw/a b c/;
Aussage eigentlich bedeutet:ähnlich, die Unterprogramm-Deklaration
sub name {...}
eigentlich ist:Da diese Bausteine führen zur compile-Zeit, alle Zeilen, die kompiliert werden, nachdem ein block ausgeführt wird, wird die Verwendung der neuen Definitionen, dass die BEGIN-Blöcke gemacht. Dies ist, wie können Sie rufen Subroutinen ohne Klammer, oder wie die verschiedenen Module "zu ändern, wie die Welt funktioniert".
END
Blöcke können verwendet werden, um aufzuräumen die änderungen, dieBEGIN
Blöcke gemacht haben, sondern es ist eher üblich, Objekte mit einerDESTROY
Methode.Wenn der Staat, dem Sie versuchen zu bereinigen, ist ein DBI-Verbindung zu tun, die in einem
END
block ist in Ordnung. Ich würde nicht erstellen Sie die Verbindung in einemBEGIN
block zwar aus mehreren Gründen. In der Regel gibt es keine Notwendigkeit für die Verbindung zur Verfügung zu compile-Zeit. Ausführen von Aktionen wie das verbinden mit einer Datenbank zur compile-Zeit drastisch verlangsamen-editor verwenden, der syntax-Prüfung (da läuftperl -c
).InformationsquelleAutor der Antwort Eric Strom
Während die anderen Antworten sind wahr, ich finde es auch erwähnenswert, die Verwendung von
BEGIN
undEND
Blöcke bei Verwendung der-n
oder-p
Schalter zu Perl.Vom http://perldoc.perl.org/perlmod.html
Für diejenigen, die nicht mit der
-n
wechseln, es sagt Perl wickeln Sie das Programm mit:http://perldoc.perl.org/perlrun.html#Command-Switches wenn Sie interessiert sind, um mehr spezifische Informationen über die Perl-Schalter.
Als Beispiel, um zu veranschaulichen die Verwendung von
BEGIN
mit der-n
Schalter, dieser Perl-Einzeiler zählt die Zeilen derls
Befehl:In diesem Fall, die
BEGIN
-block wird verwendet, um die variable$i
mit der Einstellung 1 vor der Verarbeitung der Zeilen vonls
. In diesem Beispiel wird die Ausgabe etwas wie:InformationsquelleAutor der Antwort oscfri